home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / Framework / Sources / UDispatcher.cp < prev    next >
Encoding:
Text File  |  1996-04-03  |  131.2 KB  |  4,343 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // UDispatcher.cp 
  3. // Copyright © 1984-96 by Apple Computer, Inc. All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6. #ifndef __UDISPATCHER__
  7. #include "UDispatcher.h"
  8. #endif
  9.  
  10. // MacApp
  11.  
  12. #ifndef __UBEHAVIOR__
  13. #include "UBehavior.h"
  14. #endif
  15.  
  16. #ifndef __UBUSYCURSOR__
  17. #include "UBusyCursor.h"
  18. #endif
  19.  
  20. #ifndef __UCLIPBOARDMGR__
  21. #include "UClipboardMgr.h"
  22. #endif
  23.  
  24. #if qContainer
  25.     #ifndef __UCONTAINER__
  26.     #include "UContainer.h"
  27.     #endif
  28. #endif
  29.  
  30. #ifndef __UCOREERRORMGR__
  31. #include "UCoreErrorMgr.h"
  32. #endif
  33.  
  34. #ifndef __UCOREGLOBALS__
  35. #include "UCoreGlobals.h"
  36. #endif
  37.  
  38. #ifndef __UCOREUTILITIES__
  39. #include "UCoreUtilities.h"
  40. #endif
  41.  
  42. #ifndef __UDEBUG__
  43. #include "UDebug.h"
  44. #endif
  45.  
  46. #ifndef __UDEPENDENCIES__
  47. #include "UDependencies.h"
  48. #endif
  49.  
  50. #ifndef __UDESIGNATOR__
  51. #include "UDesignator.h"
  52. #endif
  53.  
  54. #ifndef __UDOCUMENT__
  55. #include "UDocument.h"
  56. #endif
  57.  
  58. #ifndef __UERRORMGR__
  59. #include "UErrorMgr.h"
  60. #endif
  61.  
  62. #ifndef __UFILE__
  63. #include "UFile.h"
  64. #endif
  65.  
  66.  
  67. #if qContainer
  68.     #ifndef __UFILEBASEDDOCUMENT__
  69.     #include "UFileBasedDocument.h"
  70.     #endif
  71.     
  72.     #ifndef __UODPARTVIEW__
  73.     #include "UODPartView.h" 
  74.     #endif
  75. #endif
  76.  
  77. #ifndef __FLOATWINDOW__
  78. #include "FloatWindow.h"
  79. #endif
  80.  
  81. #ifndef __UGEOMETRY__
  82. #include "UGeometry.h"
  83. #endif
  84.  
  85. #ifndef __UMACAPPGLOBALS__
  86. #include "UMacAppGlobals.h"
  87. #endif
  88.  
  89. #ifndef __UMACAPPUTILITIES__
  90. #include "UMacAppUtilities.h"
  91. #endif
  92.  
  93. #ifndef __UMEMORY__
  94. #include "UMemory.h"
  95. #endif
  96.  
  97. #ifndef __UMENUMGR__
  98. #include "UMenuMgr.h"
  99. #endif
  100.  
  101. #ifndef __UPATCH__
  102. #include "UPatch.h"
  103. #endif
  104.  
  105. #ifndef __UPRINTHANDLER__
  106. #include "UPrintHandler.h"
  107. #endif
  108.  
  109. #ifndef __UOSASCRIPT__
  110. #include "UOSAScript.h"
  111. #endif
  112.  
  113. #ifndef __USCRIPTING__
  114. #include "UScripting.h"
  115. #endif
  116.  
  117. #ifndef __USEGMENTS__
  118. #include "USegments.h"
  119. #endif
  120.  
  121. #ifndef __USTREAM__
  122. #include "UStream.h"
  123. #endif
  124.  
  125. #ifndef __UTRACKER__
  126. #include "UTracker.h"
  127. #endif
  128.  
  129. #ifndef __UUNDO__
  130. #include "UUndo.h"
  131. #endif
  132.  
  133. #ifndef __UVIEWSERVER__
  134. #include "UViewServer.h"
  135. #endif
  136.  
  137. #ifndef __UWINDOW__
  138. #include "UWindow.h"
  139. #endif
  140.  
  141. // CALib
  142.  
  143. #if qContainer
  144.     #ifndef _CALIB_
  145.     #include "CALib.h"
  146.     #endif
  147. #endif
  148.  
  149. // Toolbox
  150.  
  151. #ifndef __AEREGISTRY__
  152. #include <AERegistry.h>
  153. #endif
  154.  
  155. #ifndef __DEVICES__
  156. #include <Devices.h>
  157. #endif
  158.  
  159. #ifndef __DISKINIT__
  160. #include <DiskInit.h>
  161. #endif
  162.  
  163. #ifndef __ERRORS__
  164. #include <Errors.h>
  165. #endif
  166.  
  167. #ifndef __LOWMEM__
  168. #include <LowMem.h>
  169. #endif
  170.  
  171. #ifndef __RESOURCES__
  172. #include <Resources.h>
  173. #endif
  174.  
  175. #ifndef __TOOLUTILS__
  176. #include <ToolUtils.h>
  177. #endif
  178.  
  179. // ANSI
  180.  
  181. #ifndef __STDIO__
  182. #include <stdio.h>
  183. #endif
  184.  
  185. // Other
  186.  
  187. #if defined(__MWERKS__) && (qDebug || qTheDebugger)
  188.     #ifndef __CWDEBUG__
  189.         #include "CWDebug.h"
  190.     #endif    
  191. #endif
  192.  
  193. //----------------------------------------------------------------------------------------
  194. // Constant definitions
  195. //----------------------------------------------------------------------------------------
  196.  
  197. enum SystemJustification { smSysJustLeft = 0, smSysJustRight = -1 };
  198.     // Constants to use with GetSysDirection() and SetSysDirection().
  199.  
  200.  
  201. //----------------------------------------------------------------------------------------
  202. // Global variable definitions.
  203. //----------------------------------------------------------------------------------------
  204.  
  205. TDispatcher* gDispatcher;
  206. Boolean gInitialized;
  207. AEAddressDesc gServerAddress;
  208.  
  209. Boolean    gHasODFocus;    
  210. Boolean    gHasODModalFocus;
  211.  
  212. //    Boolean hadCreditsStringList;        // does the rsrc 'STR#' == kDefaultCredits exist ?
  213. //    short lastCreditsStringIndex;        // the last CString in the STR# to be displayed
  214. //    long lastCreditsShownTicks;            // the tickcount when the last Credit was Shown
  215. //    CStringHandle originalText;            // the about box's original text (prior to credits)
  216. //    short waitTicks;                    // how long to wait between credits 
  217.  
  218. //========================================================================================
  219. // GLOBAL Procedures
  220. //========================================================================================
  221. static void DoSetupTheMenus(void* yourDataPtr);
  222.  
  223. static WindowRef GetWindowToClose();
  224.  
  225. #undef Inherited
  226.  
  227. //========================================================================================
  228. // CLASS CEventListIterator
  229. //========================================================================================
  230. #undef Inherited
  231.  
  232. #pragma segment MAApplicationRes
  233.  
  234. class CEventListIterator
  235. {
  236. public:
  237.     inline CEventListIterator(const TEventList* itsEventList) :
  238.     fCurrentIndex(itsEventList->GetSize()),    // We iterate backward over the event list
  239.     fEventList(itsEventList)
  240.     { }
  241.  
  242.     inline Boolean More()
  243.     { return (fCurrentIndex != kEmptyIndex); }
  244.         // Returns true if there are more elements to iterate over
  245.  
  246.     inline TEvent* FirstEvent()
  247.     { return this->More() ? (TEvent*)fEventList->At(fCurrentIndex) : NULL; }
  248.         // Resets the iterator to begin again and returns the value of the first index in
  249.         // the iteration
  250.  
  251.     inline TEvent* NextEvent()
  252.     { this->Advance(); return this->More() ? (TEvent*)fEventList->At(fCurrentIndex) : NULL; }
  253.         // Advances the iteration and then returns the index
  254.  
  255. protected:
  256.     inline void Advance()
  257.     { fCurrentIndex = (fCurrentIndex > 1) ? fCurrentIndex - 1 : kEmptyIndex; }
  258.         // Advances the iteration
  259.  
  260. public:
  261.     // These items are currently public for searching
  262.  
  263.     ArrayIndex fCurrentIndex;                    // current index of this iteration
  264.  
  265. protected:
  266.     const TEventList* fEventList;                        // the main event list
  267. };
  268.  
  269.  
  270. //========================================================================================
  271. // CLASS CDocumentIterator
  272. //========================================================================================
  273. #undef Inherited
  274.  
  275. //----------------------------------------------------------------------------------------
  276. // CDocumentIterator::CDocumentIterator: 
  277. //----------------------------------------------------------------------------------------
  278. #pragma segment MAApplicationRes
  279.  
  280. CDocumentIterator::CDocumentIterator(const TDispatcher* itsApplication,
  281.                                      ArrayIndex itsLowBound,
  282.                                      ArrayIndex itsHighBound,
  283.                                      Boolean itsForward) :
  284.     CObjectIterator(itsApplication ? itsApplication->fDocumentList : NULL, itsLowBound, itsHighBound, itsForward)
  285.  
  286. {
  287. } // CDocumentIterator::CDocumentIterator 
  288.  
  289. //----------------------------------------------------------------------------------------
  290. // CDocumentIterator::CDocumentIterator: 
  291. //----------------------------------------------------------------------------------------
  292. #pragma segment MAApplicationRes
  293.  
  294. CDocumentIterator::CDocumentIterator(const TDispatcher* itsApplication,
  295.                                      Boolean itsForward) :
  296.     CObjectIterator(itsApplication ? itsApplication->fDocumentList : NULL, itsForward)
  297. {
  298. } // CDocumentIterator::CDocumentIterator 
  299.  
  300. //----------------------------------------------------------------------------------------
  301. // CDocumentIterator::CDocumentIterator: 
  302. //----------------------------------------------------------------------------------------
  303. #pragma segment MAApplicationRes
  304.  
  305. CDocumentIterator::CDocumentIterator(const TDispatcher* itsApplication) :
  306.     CObjectIterator(itsApplication ? itsApplication->fDocumentList : NULL, kIterateForward)
  307. {
  308. } // CDocumentIterator::CDocumentIterator 
  309.  
  310. //----------------------------------------------------------------------------------------
  311. // CDocumentIterator::~CDocumentIterator: 
  312. //----------------------------------------------------------------------------------------
  313. #pragma segment IteratorRes
  314.  
  315. CDocumentIterator::~CDocumentIterator()
  316. {
  317. } // CDocumentIterator::~CDocumentIterator 
  318.  
  319. #if qContainer
  320. //========================================================================================
  321. // CLASS CCADocumentIterator
  322. //========================================================================================
  323.  
  324. //----------------------------------------------------------------------------------------
  325. // CCADocumentIterator::CCADocumentIterator: 
  326. //----------------------------------------------------------------------------------------
  327. #pragma segment MAApplicationRes
  328.  
  329. CCADocumentIterator::CCADocumentIterator(const TDispatcher* itsApplication,
  330.                                      ArrayIndex itsLowBound,
  331.                                      ArrayIndex itsHighBound,
  332.                                      Boolean itsForward) :
  333.     CObjectIterator(itsApplication ? itsApplication->fCADocumentList : NULL, itsLowBound, itsHighBound, itsForward)
  334.  
  335. {
  336. } // CCADocumentIterator::CCADocumentIterator 
  337.  
  338. //----------------------------------------------------------------------------------------
  339. // CDocumentIterator::CCADocumentIterator: 
  340. //----------------------------------------------------------------------------------------
  341. #pragma segment MAApplicationRes
  342.  
  343. CCADocumentIterator::CCADocumentIterator(const TDispatcher* itsApplication,
  344.                                      Boolean itsForward) :
  345.     CObjectIterator(itsApplication ? itsApplication->fCADocumentList : NULL, itsForward)
  346. {
  347. } // CCADocumentIterator::CCADocumentIterator 
  348.  
  349. //----------------------------------------------------------------------------------------
  350. // CCADocumentIterator::CCADocumentIterator: 
  351. //----------------------------------------------------------------------------------------
  352. #pragma segment MAApplicationRes
  353.  
  354. CCADocumentIterator::CCADocumentIterator(const TDispatcher* itsApplication) :
  355.     CObjectIterator(itsApplication ? itsApplication->fCADocumentList : NULL, kIterateForward)
  356. {
  357. } // CCADocumentIterator::CCADocumentIterator 
  358.  
  359. //----------------------------------------------------------------------------------------
  360. // CCADocumentIterator::~CCADocumentIterator: 
  361. //----------------------------------------------------------------------------------------
  362. #pragma segment IteratorRes
  363.  
  364. CCADocumentIterator::~CCADocumentIterator()
  365. {
  366. } // CCADocumentIterator::~CCADocumentIterator 
  367.  
  368. #endif
  369. //========================================================================================
  370. // CLASS CNoGhostDocsIterator
  371. //========================================================================================
  372. #undef Inherited
  373.  
  374. //----------------------------------------------------------------------------------------
  375. // CNoGhostDocsIterator::~CNoGhostDocsIterator: 
  376. //----------------------------------------------------------------------------------------
  377. #pragma segment MAApplicationRes
  378.  
  379. CNoGhostDocsIterator::~CNoGhostDocsIterator()
  380. {
  381. }
  382.  
  383. //----------------------------------------------------------------------------------------
  384. // CNoGhostDocsIterator::More: 
  385. //----------------------------------------------------------------------------------------
  386. #pragma segment MAApplicationRes
  387.  
  388. Boolean CNoGhostDocsIterator::More()
  389. {
  390.     Boolean more = FALSE;
  391.     
  392.     // advances iterator to next valid document
  393.     while (!more && CDocumentIterator::More())
  394.     {
  395.         if (!((TDocument*)((TSortedList*)fDynamicArray)->At(fCurrentIndex))->GetIsGhostDocument())
  396.             more = TRUE;
  397.         else
  398.             this->Advance();
  399.     }
  400.     return more;
  401. }
  402.  
  403. //========================================================================================
  404. // struct CSetupTheMenus
  405. //========================================================================================
  406.  
  407. struct CSetupTheMenus
  408. {
  409. public:
  410.     TDispatcher* fDispatcher;
  411.  
  412.     // Constructor
  413.     inline CSetupTheMenus(TDispatcher* theDispatcher) :
  414.         fDispatcher(theDispatcher)
  415.     { }
  416. };
  417.  
  418. //----------------------------------------------------------------------------------------
  419. // DoSetupTheMenus: 
  420. //----------------------------------------------------------------------------------------
  421. #pragma segment MAApplicationRes
  422.  
  423. void DoSetupTheMenus(void* /* yourDataPtr */)
  424. {
  425. #if qContainer
  426.     if (gContainerLib)
  427.     {
  428.         CAAdjustMenus();
  429.         OSErr theErr = CAError();
  430.         if (theErr != noErr)
  431.             ;        // handle the error
  432.     }
  433. #endif
  434.         
  435.     if (!gDispatcher) return;
  436.     
  437.     // Set the Undo and Redo menu items
  438. //    // to "Can't Undo" before giving the target chain a chance
  439. //    // to change it.
  440. //        gDispatcher->SetUndoText(cCantUndo);
  441. //        gDispatcher->SetRedoText(cCantUndo);
  442.     
  443.     gDispatcher->SetupUndoRedoMenus();
  444.  
  445.     gClipboardMgr->fGotClipType = FALSE;          // so CanPaste will work correctly
  446.     gDispatcher->GetTarget()->HandleSetupMenus();// Setup menus relevant to target chain 
  447.  
  448.     // Set up the menu commands that are not dependent on the target chain… 
  449.  
  450.     if (gDispatcher->fSysWindowActive)
  451.     {
  452.         Enable(cUndo, TRUE);
  453.         Enable(cCut, TRUE);
  454.         Enable(cCopy, TRUE);
  455.         Enable(cPaste, TRUE);
  456.         Enable(cClear, TRUE);
  457.  
  458.         gDispatcher->SetUndoText(cNoCommand);
  459.         gDispatcher->SetRedoText(cNoCommand);
  460.     }
  461.  
  462. #if qPerform
  463.     {
  464.         Boolean initiated = PerfMonitorInitiated();
  465.         
  466.         Enable(cPerfMonInit, !initiated);
  467.         Enable(cPerfMonDump, initiated);
  468.         Enable(cPerfMonToggle, initiated);
  469.         SetMenuState(cPerfMonToggle, kDebugBuzzStrings, bzContinuePerfMon, bzPausePerfMon, PerfMonitorEnabled());
  470.         Enable(cPerfMonEnd, initiated);
  471.     }
  472. #endif
  473.  
  474.     Enable(cAboutApp, TRUE);
  475.     Enable(-(mApple << 8), TRUE);
  476.     if (CommandEnabled(cAboutApp) && gDispatcher->InModalState())
  477.     {
  478.         WindowRef aWindowPtr = FrontWindow();
  479.         if (aWindowPtr && GetWindowVariant(aWindowPtr) == movableDBoxProc)
  480.             Enable(cAboutApp, FALSE);    // just disallow the about item
  481.         else
  482.             Enable(-(mApple << 8), FALSE);    // disallow the whole menu
  483.     }
  484.  
  485. } // DoSetupTheMenus 
  486.  
  487.  
  488. //========================================================================================
  489. // CLASS TEventList: Empty constructor to satisfy the compiler.
  490. //========================================================================================
  491. #undef Inherited
  492. #define Inherited TSortedList
  493.  
  494. #pragma segment MAInit
  495. MA_DEFINE_CLASS_M1(TEventList, Inherited);
  496.  
  497. //----------------------------------------------------------------------------------------
  498. // TEventList::TEventList: Empty constructor to satisfy the compiler. 
  499. //----------------------------------------------------------------------------------------
  500. #pragma segment ConstructorRes
  501.  
  502. TEventList::TEventList()
  503. {
  504. } // TEventList::TEventList 
  505.  
  506. //----------------------------------------------------------------------------------------
  507. // TEventList destructor
  508. //----------------------------------------------------------------------------------------
  509. #pragma segment MADestructorRes
  510.  
  511. TEventList::~TEventList()
  512. {
  513. }
  514.  
  515. //----------------------------------------------------------------------------------------
  516. // TEventList::Compare: 
  517. //----------------------------------------------------------------------------------------
  518. #pragma segment MAApplicationRes
  519.  
  520. CompareResult TEventList::Compare(TObject* item1,
  521.                                   TObject* item2)
  522. {
  523.     CompareResult returnVal = kItem1EqualItem2;
  524.  
  525.     // We want higher priority events at the end of the queue so we can delete from the
  526.     // end of the list. This will save us a block move in DeleteElementsAt.
  527.     if (((TEvent *)item1)->fPriority > ((TEvent *)item2)->fPriority)
  528.         returnVal = kItem1LessThanItem2;
  529.     else if (((TEvent *)item1)->fPriority < ((TEvent *)item2)->fPriority)
  530.         returnVal = kItem1GreaterThanItem2;
  531.  
  532.     return returnVal;
  533. } // TEventList::Compare 
  534.  
  535. //----------------------------------------------------------------------------------------
  536. // TEventList::IEventList: 
  537. //----------------------------------------------------------------------------------------
  538. #pragma segment MAInit
  539.  
  540. void TEventList::IEventList()
  541. {
  542.     this->ISortedList();
  543. } // TEventList::IEventList 
  544.  
  545. //----------------------------------------------------------------------------------------
  546. // TEventList::Insert: 
  547. //----------------------------------------------------------------------------------------
  548. #pragma segment MAApplicationRes
  549.  
  550. void TEventList::Insert(TObject* item)    // override 
  551. {
  552.     MAVolatileInit(Boolean, oldObjectPerm, AllocateObjectsFromPerm(FALSE));
  553.     
  554.     FailInfo fi;
  555.     Try(fi)
  556.     {
  557.         Inherited::Insert(item);
  558.         fi.Success();
  559.     }
  560.     else
  561.     {
  562.         AllocateObjectsFromPerm(oldObjectPerm);
  563.         fi.ReSignal();
  564.     }
  565.     
  566.     AllocateObjectsFromPerm(oldObjectPerm);
  567. } // TEventList::Insert 
  568.  
  569. //========================================================================================
  570. // CLASS TEventRetrieverCommand
  571. //========================================================================================
  572. #undef Inherited
  573. #define Inherited TCommand
  574.  
  575. #pragma segment MASelCommand
  576. MA_DEFINE_CLASS_M1(TEventRetrieverCommand, Inherited);
  577.  
  578. //----------------------------------------------------------------------------------------
  579. // TEventRetrieverCommand: Empty constructor to satisfy the compiler.
  580. //----------------------------------------------------------------------------------------
  581. #pragma segment ConstructorRes
  582.  
  583. TEventRetrieverCommand::TEventRetrieverCommand()
  584. {
  585. } // TEventRetrieverCommand::TEventRetrieverCommand
  586.  
  587. //----------------------------------------------------------------------------------------
  588. // TEventRetrieverCommand destructor
  589. //----------------------------------------------------------------------------------------
  590. #pragma segment MADestructorRes
  591.  
  592. TEventRetrieverCommand::~TEventRetrieverCommand()
  593. {
  594. }
  595.  
  596. //----------------------------------------------------------------------------------------
  597. // TEventRetrieverCommand::IEventRetrieverCommand: 
  598. //----------------------------------------------------------------------------------------
  599. #pragma segment MASelCommand
  600.  
  601. void TEventRetrieverCommand::IEventRetrieverCommand(CommandNumber itsCommandNumber)
  602. {
  603.     this->ICommand(itsCommandNumber, gDispatcher, kCantUndo, kDoesNotCauseChange, NULL);
  604.  
  605.     // Hang around 
  606.     fFreeOnCompletion = FALSE;
  607.     fRecurring = TRUE;
  608.  
  609.     // Let more important stuff happen first 
  610.     fPriority = kPriorityLow;
  611. } // TEventRetrieverCommand::IEventRetrieverCommand 
  612.  
  613. //----------------------------------------------------------------------------------------
  614. // TEventRetrieverCommand::NeedsToUnloadAllSegments: 
  615. //----------------------------------------------------------------------------------------
  616. #pragma segment MAApplicationRes
  617.  
  618. Boolean TEventRetrieverCommand::NeedsToUnloadAllSegments()
  619. {
  620.     return FALSE;
  621. } // TEventRetrieverCommand::NeedsToUnloadAllSegments 
  622.  
  623. //----------------------------------------------------------------------------------------
  624. // TEventRetrieverCommand::DoIt: 
  625. //----------------------------------------------------------------------------------------
  626. #pragma segment MAApplicationRes
  627.  
  628. void TEventRetrieverCommand::DoIt()
  629. {
  630.     gDispatcher->PollToolboxEvent(gDispatcher->fAllowApplicationToSleep);
  631. } // TEventRetrieverCommand::DoIt 
  632.  
  633.  
  634. //========================================================================================
  635. // CLASS TDispatcher
  636. //========================================================================================
  637. #undef Inherited
  638. #define Inherited TCommandHandler
  639.  
  640. #pragma segment MAInit
  641. MA_DEFINE_CLASS_M2(TDispatcher, Inherited, MDefaultScriptableObject);
  642.  
  643. //----------------------------------------------------------------------------------------
  644. // TDispatcher constructor 
  645. //----------------------------------------------------------------------------------------
  646. #pragma segment MAInit
  647.  
  648. TDispatcher::TDispatcher() :
  649.     MDefaultScriptableObject(cApplication)
  650. {
  651.     // This is a special case.  It needs to be available as soon as possible.
  652.     gDispatcher = this;
  653.  
  654.     fMainFileType = 'TEXT';
  655.     fCreator = '\?\?\?\?';
  656.     fAllowApplicationToSleep = TRUE;
  657.     fAlwaysTrackCursor = FALSE;
  658.     fDone = FALSE;
  659.     fProcessNumber.highLongOfPSN = kNoProcess;
  660.     fProcessNumber.lowLongOfPSN = kNoProcess;
  661.     fClickCount = 0;
  662.     fEventList = NULL;
  663.     fCursorRegion = NULL;
  664.     fDocumentList = NULL;
  665.     fEventLevel = 1;                        // Prevents UnloadAllSegs from getting called
  666.                                             // if a modal dialogs is used befure starting
  667.                                             // the main event loop
  668.     fFreeWindowList = NULL;
  669.     fHeadCohandler = NULL;
  670.     fHelpRegion = NULL;
  671.     fIdlePhase = idleEnd;
  672.     fLastClickPart = inDesk;
  673.     fLastMousePoint = gZeroPt;
  674.     fLastUpTime = TickCount();
  675. //        fLaunchWithNewDocument = TRUE;
  676.     fLowSpaceInterval = kLowSpaceInterval;
  677.     fMainEventMask = everyEvent;
  678.     
  679. #if qContainer
  680.     fCADocumentList = NULL;
  681.     gHasODFocus  = TRUE;
  682.     gHasODModalFocus = TRUE;
  683.     
  684.     if (gContainerLib)
  685.     {
  686.         fDisplayedMenus = kMBarOpenDoc;
  687.         fCurrentDocument = 0;
  688.     }
  689.     else
  690. #endif
  691.     fDisplayedMenus = kMBarDisplayed;
  692.     fOtherMenus = kMBarNotDisplayed;
  693.     fMBarHierarchical = kMBarHierarchical;
  694.     fNextSpaceMessage = TickCount();
  695.     fSleepRegion = NULL;
  696.     fSysWindowActive = FALSE;
  697.     fTarget = this;
  698.     fUndoCommand = cNoCommand;
  699.     fRedoCommand = cNoCommand;
  700.     //    fUndoState = kShowUndo;
  701. //    #if qDebug
  702. //        fDebugFlagsWindow = NULL;
  703. //    #endif
  704.     fWantKeyUpEvents = FALSE;
  705. } // TDispatcher::TDispatcher 
  706.  
  707. //----------------------------------------------------------------------------------------
  708. // TDispatcher destructor
  709. //----------------------------------------------------------------------------------------
  710. #pragma segment MADestructorRes
  711.  
  712. TDispatcher::~TDispatcher()
  713. {
  714. }
  715.  
  716. //----------------------------------------------------------------------------------------
  717. // TDispatcher::IDispatcher: 
  718. //----------------------------------------------------------------------------------------
  719. #pragma segment MAInit
  720.  
  721. void TDispatcher::IDispatcher(OSType itsMainFileType,
  722.                             OSType itsCreator)
  723. {
  724.     this->ICommandHandler(NULL);
  725.  
  726.     FailInfo fi;
  727.     Try(fi)
  728.     {
  729.         fMainFileType = itsMainFileType;
  730.         fCreator = itsCreator;
  731.     
  732.         fSleepRegion = MakeNewRgn();
  733.         fCursorRegion = MakeNewRgn();
  734.         fHelpRegion = MakeNewRgn();
  735.     
  736.         FailOSErr(GetCurrentProcess(&fProcessNumber));
  737.     
  738.         fFreeWindowList = NewList();
  739. #if qDebug
  740.         fFreeWindowList->SetEltType(&TWindow::fgClassDesc);
  741. #endif
  742.     
  743.         fDocumentList = NewList();
  744. #if qDebug
  745.         fDocumentList->SetEltType(&TDocument::fgClassDesc);
  746. #endif
  747.     
  748.  
  749. #if qContainer
  750.         fCADocumentList = NewList(); //create list to hold list of container documents.
  751.         fCADocumentList->IList(); 
  752. #endif 
  753.  
  754.     
  755.         // Posted commands won't go anywhere until we create the queue 
  756.         TEventList * anEventList = new TEventList;
  757.         anEventList->IEventList();
  758.         fEventList = anEventList;
  759. #if qDebug
  760.         fEventList->SetEltType(&TEvent::fgClassDesc);
  761. #endif
  762.         
  763.         // Allocate the global dependencyspace gMacAppDependencySpace
  764.         this->DoMakeDependencySpace();
  765.         
  766.         // Make the command that operates the main Event Loop 
  767.         TEventRetrieverCommand * aEventCommand = new TEventRetrieverCommand;
  768.         aEventCommand->IEventRetrieverCommand(cNoCommand);
  769.         this->PostCommand(aEventCommand);
  770.     
  771.         // Create the MenuBar manager object
  772.         gMenuBarManager = this->MakeMenuBarManager();
  773.     
  774.         this->DoMakeViewServer();                    // creates the view server
  775.         
  776.         // OSADispatcher setup
  777.         if (!TOSADispatcher::fgDispatcher)
  778.             InitUScripting();
  779.     
  780.         TOSADispatcher::fgDispatcher->SetDefaultTarget(this);
  781.  
  782.         TPrintHandler::gPrintHandler->DispatcherIsAvailable();
  783.         
  784.         fi.Success();
  785.     }
  786.     else
  787.     {
  788. #if qDebug
  789.         ProgramBreak("Can't initialize the event loop object!");
  790. #endif
  791.         this->Free();
  792.         gDispatcher = NULL;
  793.         fi.ReSignal();
  794.     }
  795. } // TDispatcher::IDispatcher 
  796.  
  797. //----------------------------------------------------------------------------------------
  798. // TDispatcher::MakeMenuBarManager: 
  799. //----------------------------------------------------------------------------------------
  800. #pragma segment MAInit
  801.  
  802. // This function is called by IDispatcher to create the menu bar manager object.
  803. TMenuBarManager* TDispatcher::MakeMenuBarManager()
  804. {
  805.     TMenuBarManager* theMenuBarManager = new TMenuBarManager;
  806.     theMenuBarManager->IMenuBarManager(fOtherMenus);
  807.     
  808.     return theMenuBarManager;
  809. } // TDispatcher::MakeMenuBarManager 
  810.  
  811. //----------------------------------------------------------------------------------------
  812. // TDispatcher::AboutToLoseControl: 
  813. //----------------------------------------------------------------------------------------
  814. #pragma segment MAActivate
  815.  
  816. void TDispatcher::AboutToLoseControl(Boolean convertClipboard)
  817. {
  818.     gClipboardMgr->AboutToLoseControl(convertClipboard);
  819.  
  820.     // Let all windows know that we're losing control - e.g. so floaters can hide
  821.     // themselves
  822.     CWMgrIterator iter;
  823.  
  824.     for (WindowRef aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow())
  825.     {
  826.         TWindow * aWindow = this->WMgrToWindow(aWinPtr);
  827.         if (aWindow)
  828.             aWindow->AboutToLoseControl();
  829.     }
  830.  
  831.     this->Changed(mAboutToLoseControl, this);
  832.  
  833.     this->ActivateBusyCursor(FALSE);            // Don't want busy cursor while in DA
  834.  
  835. } // TDispatcher::AboutToLoseControl 
  836.  
  837. //----------------------------------------------------------------------------------------
  838. // TDispatcher::InteractWithUser: 
  839. //----------------------------------------------------------------------------------------
  840. #pragma segment MAApplicationRes
  841.  
  842. OSErr TDispatcher::InteractWithUser(long timeOutInTicks,
  843.                                     NMRecPtr nmReqPtr, 
  844.                                     AEIdleUPP idleProc)
  845. {
  846.     long interactTimeout;
  847.     
  848.     if (timeOutInTicks == kMacAppTimeout)
  849.     {
  850.         if (TOSADispatcher::fgDispatcher && TOSADispatcher::fgDispatcher->GetDispatchLevel() > 0)
  851.             interactTimeout = kAEDefaultTimeout;
  852.         else
  853.             interactTimeout = kNoTimeOut;
  854.     }
  855.     else
  856.         interactTimeout = timeOutInTicks;
  857.  
  858.     return AEInteractWithUser(interactTimeout, nmReqPtr, idleProc);
  859. } // TDispatcher::InteractWithUser
  860.  
  861. //----------------------------------------------------------------------------------------
  862. // TDispatcher::ActivateBusyCursor: 
  863. //----------------------------------------------------------------------------------------
  864. #pragma segment MAApplicationRes
  865.  
  866. Boolean TDispatcher::ActivateBusyCursor(Boolean entering)
  867. {
  868.     return (gBusyCursor ? gBusyCursor->Activate(entering) : FALSE);
  869. } // TDispatcher::ActivateBusyCursor 
  870.  
  871. //----------------------------------------------------------------------------------------
  872. // TDispatcher::AddDocument: 
  873. //----------------------------------------------------------------------------------------
  874. #pragma segment MAOpen
  875.  
  876. void TDispatcher::AddDocument(TDocument* aNewDocument)
  877. {
  878.     if (fDocumentList)
  879.         fDocumentList->Insert(aNewDocument);
  880. } // TDispatcher::AddDocument 
  881.  
  882. //----------------------------------------------------------------------------------------
  883. // TDispatcher::AddWindow: 
  884. //----------------------------------------------------------------------------------------
  885. #pragma segment MAOpen
  886.  
  887. void TDispatcher::AddWindow(TWindow* aWindow)
  888. {
  889.     // Protect against double installation
  890.     if (fFreeWindowList && (fFreeWindowList->GetIdentityItemNo(aWindow) == 0))
  891.         fFreeWindowList->Insert(aWindow);
  892. } // TDispatcher::AddWindow 
  893.  
  894. #if qContainer
  895. //----------------------------------------------------------------------------------------
  896. // TDispatcher::AddCADocument: 
  897. //----------------------------------------------------------------------------------------
  898. #pragma segment MAOpen
  899.  
  900. void TDispatcher::AddCADocument(TFileBasedDocument* aNewDocument)
  901. {
  902.     //•••GJC
  903.     //this needs better support other than a kludgy cast
  904.  
  905.     if (fCADocumentList)
  906.         fCADocumentList->Insert((TObject*)aNewDocument);
  907. } // TDispatcher::AddCADocument 
  908. #endif
  909.  
  910. //----------------------------------------------------------------------------------------
  911. // TDispatcher::AlertFilter: AlertFilter is a default filterProc used by MacAppAlert if
  912. // the filterProc passed in is NULL. It maps key strokes to the first character of button
  913. // item titles. It also hands off activate and update processing to gDispatcher if we're
  914. // not being called from an error condition or while nested.
  915. //----------------------------------------------------------------------------------------
  916. #pragma segment MAGlobalsRes
  917. // Don't require a segment load for this 
  918.  
  919. Boolean TDispatcher::AlertFilter(DialogRef theDialog,
  920.                                   EventRecord& theEvent,
  921.                                   short& itemHit)
  922.  
  923. {
  924.     MAVolatileInit(Boolean, returnValue, FALSE);
  925.  
  926.     MAVolatileInit(Boolean, oldInFilterState, gInFilter);
  927.     gInFilter = TRUE;
  928.     
  929.     // First call the minimal alert filter; if it does not handle the
  930.     // event, do some more complex handling
  931.     returnValue = MinimalAlertFilter(theDialog, theEvent, itemHit);
  932.     if (returnValue == FALSE)
  933.     {
  934.         FailInfo fi;
  935.         Try(fi)
  936.         {
  937.             // Wouldn't want MacApp to get lied to about where the focus _Actually_ is 
  938.             if (!gInhibitNestedHandling && !oldInFilterState)
  939.                 this->InvalidateFocus();
  940.     
  941.             switch (theEvent.what)
  942.             {
  943.                 // this is the first event the alert gets, use it to initialize the global buffer
  944.                 case activateEvt:
  945.                 case updateEvt:
  946.                     if ((((DialogRef)theEvent.message) != theDialog) && (!gInhibitNestedHandling && !oldInFilterState))
  947.                         {
  948.                             GrafPtr savePort;
  949.                             GetPort(&savePort);
  950.                             
  951.                             Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  952.                             TToolboxEvent * event = new TToolboxEvent;
  953.                             AllocateObjectsFromPerm(oldObjectPerm);
  954.                             event->IToolboxEvent(this, theEvent);
  955.                             event->Process();
  956.                             
  957.                             SetPort(savePort);
  958.                         }
  959.                     break;
  960.     
  961.                 // let's determine if the key pressed corresponds to our button titles
  962.                 case keyDown:
  963.                 {
  964.                     static TToolboxEvent* bufferedKeyEvent;        // Must be a global, since it's used each
  965.                                                                 // time the alert filter is entered. (It
  966.                                                                 // could be a field of TDispatcher...)
  967.  
  968.                     Boolean needsSecondaryEvent = FALSE;
  969.                     if (!bufferedKeyEvent)
  970.                     {
  971.                         Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  972.                         bufferedKeyEvent = new TToolboxEvent;
  973.                         AllocateObjectsFromPerm(oldObjectPerm);
  974.                         needsSecondaryEvent = bufferedKeyEvent->IToolboxEvent(this, theEvent);
  975.                     }
  976.                     else
  977.                         bufferedKeyEvent->AddSecondaryKeyEvent(theEvent);
  978.                     
  979.                     if (!needsSecondaryEvent)
  980.                     {
  981.                         this->GetTarget()->KeyEventToComponents(bufferedKeyEvent);// Find out what keys were _REALLY_ pressed
  982.                         
  983.                         
  984.                         if (CompareAlertKeysToItem(theDialog, bufferedKeyEvent->fText, itemHit))
  985.                         {
  986.                             DoAlertKeyDown(theDialog, itemHit);
  987.                             returnValue = TRUE;
  988.                         }
  989.                         bufferedKeyEvent = (TToolboxEvent*)FreeIfObject(bufferedKeyEvent);
  990.                     }
  991.                 }
  992.             }
  993.     
  994.             // Idle but only if _REALLY_ necessary 
  995.             EventRecord anEvent;
  996.             if (!gInhibitNestedHandling && !oldInFilterState && !EventAvail(everyEvent, &anEvent))
  997.                 this->Idle(fIdlePhase);
  998.     
  999.             fi.Success();
  1000.         }
  1001.         else // Recover
  1002.         {
  1003.             // Don't ReSignal -- called by Toolbox
  1004.         }
  1005.     }
  1006.     gInFilter = oldInFilterState;
  1007.  
  1008.     return returnValue;
  1009. } // TDispatcher::AlertFilter 
  1010.  
  1011. //----------------------------------------------------------------------------------------
  1012. // TDispatcher::AppleEventIdleProc: 
  1013. //----------------------------------------------------------------------------------------
  1014. #pragma segment MAGlobalsRes
  1015. // Don't require a segment load for this 
  1016.  
  1017. Boolean TDispatcher::AppleEventIdleProc(EventRecord& theEventRecord,
  1018.                                          long&/* sleepTime */ ,
  1019.                                          RgnHandle&/* mouseRgn */ )
  1020. {
  1021.     if ((theEventRecord.what == activateEvt) || (theEventRecord.what == updateEvt))
  1022.     {
  1023.         Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  1024.         TToolboxEvent* event = new TToolboxEvent;
  1025.         AllocateObjectsFromPerm(oldObjectPerm);
  1026.         event->IToolboxEvent(this, theEventRecord);
  1027.         event->Process();
  1028.     }
  1029.     return FALSE;
  1030. } // TDispatcher::AppleEventIdleProc 
  1031.  
  1032. //----------------------------------------------------------------------------------------
  1033. // TDispatcher::StandardFileFilter: 
  1034. //----------------------------------------------------------------------------------------
  1035. #pragma segment MAGlobalsRes
  1036. // Don't require a segment load for this 
  1037.  
  1038. Boolean TDispatcher::StandardFileFilter(DialogRef /* theDialog */,
  1039.                                          EventRecord& theEvent,
  1040.                                          short& /* itemHit */,
  1041.                                          void* /* yourDataPtr */ )
  1042. {
  1043.     this->InvalidateFocus();
  1044.     switch (theEvent.what)
  1045.     {
  1046.         case activateEvt:
  1047.         case updateEvt:
  1048.             // check if intended for a MacApp window
  1049.             if (!this->WMgrToWindow((WindowRef)theEvent.message))
  1050.                 break;
  1051.             // drop thru to processing the event
  1052.         case osEvt:
  1053.         case kHighLevelEvent:
  1054.             {
  1055.                 GrafPtr savePort;
  1056.                 
  1057.                 GetPort(&savePort);                // If the port get changed behind us
  1058.                                                 // the dialog can't find its controls
  1059.                 
  1060.                 Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  1061.                 TToolboxEvent* event = new TToolboxEvent;
  1062.                 AllocateObjectsFromPerm(oldObjectPerm);
  1063.                 event->IToolboxEvent(NULL, theEvent);
  1064.                 ++fEventLevel;
  1065.                 event->Process();
  1066.                 --fEventLevel;
  1067.                 
  1068.                 SetPort(savePort);
  1069.             }
  1070.             break;
  1071.     }
  1072.  
  1073.     return FALSE;                                // did not take the event
  1074. } // TDispatcher::StandardFileFilter 
  1075.  
  1076. //----------------------------------------------------------------------------------------
  1077. // TDispatcher::FindDocument: 
  1078. //----------------------------------------------------------------------------------------
  1079. #pragma segment MAFile
  1080.  
  1081. TDocument* TDispatcher::FindDocument(TFile* aFile)
  1082. {
  1083.     CDocumentIterator iter(this);
  1084.  
  1085.     for (TDocument * aDocument = iter.FirstDocument(); iter.More(); aDocument = iter.NextDocument())
  1086.         if (aDocument->FindDocument(aFile))
  1087.             return aDocument;
  1088.     return NULL;                                // No document already open
  1089. } // TDispatcher::FindDocument 
  1090.  
  1091. //----------------------------------------------------------------------------------------
  1092. // TDispatcher::Beep: 
  1093. //----------------------------------------------------------------------------------------
  1094. #pragma segment MAApplicationRes
  1095.  
  1096. void TDispatcher::Beep(short duration)
  1097. {
  1098.     SysBeep(duration);
  1099. } // TDispatcher::Beep 
  1100.  
  1101. //----------------------------------------------------------------------------------------
  1102. // TDispatcher::Close: 
  1103. //----------------------------------------------------------------------------------------
  1104. #pragma segment MATerminate
  1105.  
  1106. void TDispatcher::Close()
  1107. {
  1108.     // Close down the cohandler chain.  Add a block for failure handling
  1109.     {
  1110.         CHandlerIterator iter(fHeadCohandler);
  1111.  
  1112.         for (TEventHandler * aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler())
  1113.             FreeIfObject(aHandler);
  1114.     }
  1115.  
  1116.     gClipboardMgr->Close();
  1117.  
  1118.     gViewServer = (TViewServer *)FreeIfObject(gViewServer); // won't be creating any more views...
  1119.     
  1120. #if qAttachable
  1121.     // Toss any attached script
  1122.     this->FreeOSAScript();
  1123. #endif
  1124.  
  1125. } // TDispatcher::Close 
  1126.  
  1127. //----------------------------------------------------------------------------------------
  1128. // TDispatcher::CloseToolboxWindow: 
  1129. //----------------------------------------------------------------------------------------
  1130. #pragma segment MAClose
  1131.  
  1132. void TDispatcher::CloseToolboxWindow(WindowRef aWMgrWindow)
  1133. {
  1134.     TWindow* aWindow = this->WMgrToWindow(aWMgrWindow);
  1135.     if (aWindow)
  1136.         aWindow->CloseByUser(cClose);
  1137.     else
  1138.         HideWindow(aWMgrWindow);
  1139. } // TDispatcher::CloseToolboxWindow 
  1140.  
  1141. //----------------------------------------------------------------------------------------
  1142. // TDispatcher::CountClicks: 
  1143. //----------------------------------------------------------------------------------------
  1144. #pragma segment MAApplicationRes
  1145.  
  1146. short TDispatcher::CountClicks(TToolboxEvent* event,
  1147.                                 short whereMouseDown)
  1148. {
  1149.     short newClickCount;
  1150.  
  1151.     newClickCount = 1;
  1152.  
  1153.     if ((whereMouseDown == fLastClickPart) &&    // clicked in the same place… 
  1154.         (fClickCount > 0) &&                    // not the first click… 
  1155.         (event->fEventRecord.when - fLastUpTime < LMGetDoubleTime()) &&// close enough in time… 
  1156.         this->GetTarget()->DoMultiClick(fLastMousePoint, event->fEventRecord.where))// close enough in space
  1157.         newClickCount = fClickCount + 1;
  1158.  
  1159.     fLastMousePoint = event->fEventRecord.where;
  1160.  
  1161.     fLastClickPart = whereMouseDown;
  1162.     fClickCount = newClickCount;
  1163.     return newClickCount;
  1164. } // TDispatcher::CountClicks 
  1165.  
  1166. //----------------------------------------------------------------------------------------
  1167. // TDispatcher::DeleteDocument: 
  1168. //----------------------------------------------------------------------------------------
  1169. #pragma segment MAClose
  1170.  
  1171. void TDispatcher::DeleteDocument(TDocument* docToDelete)
  1172. {
  1173.     if (fDocumentList)
  1174.         fDocumentList->Delete(docToDelete);
  1175. /*    
  1176. #if qContainer
  1177.     if (gContainerLib && !fDone && (!fDocumentList || (fDocumentList->fSize == 0)))
  1178.         this->DoMenuCommand(cQuit);
  1179. #endif
  1180. */
  1181. } // TDispatcher::DeleteDocument 
  1182.  
  1183. //----------------------------------------------------------------------------------------
  1184. // TDispatcher::DeleteWindow: 
  1185. //----------------------------------------------------------------------------------------
  1186. #pragma segment MAApplicationRes
  1187.  
  1188. void TDispatcher::DeleteWindow(TWindow* windowToDelete)
  1189. {
  1190.     if (fFreeWindowList)
  1191.         fFreeWindowList->Delete(windowToDelete);
  1192. } // TDispatcher::DeleteWindow 
  1193.  
  1194. #if qContainer
  1195. //----------------------------------------------------------------------------------------
  1196. // TDispatcher::DeleteCADocument: 
  1197. //----------------------------------------------------------------------------------------
  1198. #pragma segment MAClose
  1199.  
  1200. void TDispatcher::DeleteCADocument(TFileBasedDocument* docToDelete)
  1201. {
  1202.     //••• gjc this needs better support other than a kludgy cast
  1203.     if (fCADocumentList)
  1204.         fCADocumentList->Delete((TObject*)docToDelete);
  1205. } // TDispatcher::DeleteDocument 
  1206. #endif
  1207.  
  1208. //----------------------------------------------------------------------------------------
  1209. // TDispatcher::DispatchEvent: 
  1210. //----------------------------------------------------------------------------------------
  1211. #pragma segment MAApplicationRes
  1212.  
  1213. void TDispatcher::DispatchEvent(TToolboxEvent* event)
  1214. {
  1215.     // For Toolbox events, fIdentifier == fEventRecord.what 
  1216.     if (event)
  1217.     {
  1218. #if qContainer
  1219.         if (gContainerLib && (event->fIdentifier != mouseDown))
  1220.         {
  1221.             CAEventInfo eventInfo;
  1222.             Boolean handled = CADispatchEvent(&event->fEventRecords[0], &eventInfo);
  1223.             if (event->fDoubleEvent)
  1224.                 handled = CADispatchEvent(&event->fEventRecords[1], &eventInfo);
  1225.             if (handled)
  1226.                 return;
  1227.         }
  1228. #endif
  1229.  
  1230.         switch (event->fIdentifier)
  1231.         {
  1232.             case mouseUp:
  1233.                 this->HandleMouseUp(event);
  1234.                 break;
  1235.  
  1236.             case mouseDown:
  1237.                 this->HandleMouseDown(event);
  1238.                 break;
  1239.  
  1240.             case activateEvt:
  1241.                 this->HandleActivateEvent(event);
  1242.                 break;
  1243.  
  1244.             case updateEvt:
  1245.                 this->HandleUpdateEvent(event);
  1246.                 break;
  1247.  
  1248.             case keyDown:
  1249.             case autoKey:
  1250.                 this->HandleKeyDownEvent(event);
  1251.                 break;
  1252.  
  1253.             case keyUp:
  1254.                 // A MultiFinder™ bug (at least up to 6.0) keep us from reliably getting
  1255.                 // keyUp events after minor context switches (background updates, etc.).
  1256.                 // It replaces the global event mask (which we would have had to change to
  1257.                 // get keyups in the first place) with the wrong mask. Fixed in system 7.0
  1258.  
  1259.                 this->HandleKeyUpEvent(event);
  1260.                 break;
  1261.  
  1262.             case diskEvt:
  1263.                 this->HandleDiskEvent(event);
  1264.                 break;
  1265.  
  1266.             case osEvt:
  1267.                 this->HandleSystemEvent(event);
  1268.                 break;
  1269.  
  1270.             case kHighLevelEvent:
  1271.                 this->HandleHighLevelEvent(event);
  1272.                 break;
  1273.  
  1274.             default:
  1275.                 this->HandleAlienEvent(event);
  1276.                 break;
  1277.         }
  1278.     }
  1279. } // TDispatcher::DispatchEvent 
  1280.  
  1281. //----------------------------------------------------------------------------------------
  1282. // TDispatcher::DoCommandKeyEvent: 
  1283. //----------------------------------------------------------------------------------------
  1284. #pragma segment MAApplicationRes
  1285.  
  1286. void TDispatcher::DoCommandKeyEvent(TToolboxEvent* event)// override 
  1287. {
  1288.     if (!event->IsAutoKeyEvent())
  1289.     {
  1290.         this->SetupTheMenus();
  1291.  
  1292.         // == THIS =======================================================================================
  1293.         // Optional support for case sensitive command keys.
  1294.         // Use the following line because
  1295.         // KeyEventToComponents returns the correct character for shifted keys when the
  1296.         // command key is down. That lets us test for things like command-period
  1297.         // correctly. So in order to be backward compatible (sigh) we now have to ignore
  1298.         // the _correct_ char that is passed in (and is in event->fText) and use the
  1299.         // old ToolBox supplied unPasteurized character that is left in the actual
  1300.         // EventRecord
  1301.         //
  1302.         // long menuKeyResult = MenuKey(event->fText[1]);
  1303.         // if (event->fDoubleEvent)
  1304.         //         menuKeyResult = MenuKey(event->fText[2]);
  1305.  
  1306.  
  1307.         // == OR THIS ====================================================================================
  1308.         // Optional support for the latest version (1.2) of Mercutio MDEF which allows the
  1309.         // display and processing of Option and Shifted command keys.
  1310.         // http://camis.stanford.edu/people/felciano/personal/mercutio/index.html
  1311.         //
  1312.         // const mMercutioMenu = xxx; // ID of any menu that uses the Mercutio MDEF
  1313.         //
  1314.         // MenuHandle anMHandle = MAGetMenu(mMercutioMenu);
  1315.         // long menuKeyResult = MDEF_MenuKey(event->fEventRecords[0].message, event->fEventRecords[0].modifiers, anMHandle);
  1316.         // if (event->fDoubleEvent)
  1317.         //         menuKeyResult = MDEF_MenuKey(event->fEventRecords[1].message, event->fEventRecords[1].modifiers, anMHandle);
  1318.  
  1319.  
  1320.         // == OR THIS ====================================================================================
  1321.         // Ordinary case and modifier insensitive command keys
  1322.         long menuKeyResult = MenuKey((unsigned char)(((event->fEventRecords[0].message) & charCodeMask)));
  1323.         if (event->fDoubleEvent)
  1324.             menuKeyResult = MenuKey((unsigned char)(((event->fEventRecords[1].message) & charCodeMask)));
  1325.  
  1326.         this->DispatchMenuEvent(event, menuKeyResult);
  1327.     }
  1328.     else
  1329.         Inherited::DoCommandKeyEvent(event);
  1330.         
  1331. } // TDispatcher::DoCommandKeyEvent 
  1332.  
  1333. //----------------------------------------------------------------------------------------
  1334. // TDispatcher::DoKeyEvent: 
  1335. //----------------------------------------------------------------------------------------
  1336. #pragma segment MAApplicationRes
  1337.  
  1338. void TDispatcher::DoKeyEvent(TToolboxEvent* event)// override 
  1339. {
  1340.     CommandNumber aCommand = cNoCommand;
  1341.  
  1342.     switch (event->fKeyCode)
  1343.     {
  1344.         case kF1VirtualCode:
  1345.             aCommand = cUndo;
  1346.             break;
  1347.  
  1348.         case kF2VirtualCode:
  1349.             aCommand = cCut;
  1350.             break;
  1351.  
  1352.         case kF3VirtualCode:
  1353.             aCommand = cCopy;
  1354.             break;
  1355.  
  1356.         case kF4VirtualCode:
  1357.             aCommand = cPaste;
  1358.             break;
  1359.  
  1360.         case kClearVirtualCode:
  1361.             aCommand = cClear;
  1362.             break;
  1363.     }
  1364.  
  1365.     if (aCommand != cNoCommand)
  1366.     {
  1367.         this->SetupTheMenus();
  1368.         if (CommandEnabled(aCommand))
  1369.             this->GetTarget()->HandleMenuCommand(aCommand);
  1370.     }
  1371.     else
  1372.         Inherited::DoKeyEvent(event);
  1373. } // TDispatcher::DoKeyEvent 
  1374.  
  1375. //----------------------------------------------------------------------------------------
  1376. // TDispatcher::DoMakeDocument: 
  1377. //----------------------------------------------------------------------------------------
  1378.  
  1379. //----------------------------------------------------------------------------------------
  1380. // TDispatcher::DoMakeFile: 
  1381. //----------------------------------------------------------------------------------------
  1382. #pragma segment MAOpen
  1383.  
  1384. TFile* TDispatcher::DoMakeFile(CommandNumber)
  1385. {
  1386.     return NewFile(fMainFileType, fCreator, kUsesDataFork, kUsesRsrcFork, !kDataOpen, !kRsrcOpen);
  1387. } // TDispatcher::DoMakeFile 
  1388.  
  1389. //----------------------------------------------------------------------------------------
  1390. // TDispatcher::DoMenuCommand: 
  1391. //----------------------------------------------------------------------------------------
  1392. #pragma segment MASelCommand
  1393.  
  1394. void TDispatcher::DoMenuCommand(CommandNumber aCommandNumber)
  1395. {
  1396.     // ===================================================================================
  1397.     // Some commands will be posted to perform actions that must _ALWAYS_ be available.
  1398.     // The allocation cannot be allowed to fail. So we do a temp allocation which by
  1399.     // definition cannot be allowed to fail. This strategy is used wherever we want to use
  1400.     // command objects but don't want to leave the user twisting in the breeze. NOTE:
  1401.     // Don't forget to allow for this memory in your mem! resource if you copy this style
  1402.     // in your own code.
  1403.     // ===================================================================================
  1404.  
  1405.     switch (aCommandNumber)
  1406.     {
  1407.         case cUndo:
  1408.             {
  1409.                 Boolean oldTempAlloc = TemporaryAllocation(TRUE);
  1410.                 Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  1411.  
  1412.                 TUndoCommand* undoCommand = new TUndoCommand;
  1413.                 undoCommand->IUndoCommand(aCommandNumber);
  1414.                 undoCommand->fUseAppleEvent = TRUE;
  1415.                 this->PostCommand(undoCommand);
  1416.                 
  1417.                 TemporaryAllocation(oldTempAlloc);
  1418.                 AllocateObjectsFromPerm(oldObjectPerm);
  1419.             }
  1420.             break;
  1421.  
  1422.         case cRedo:
  1423.             {
  1424.                 Boolean oldTempAlloc = TemporaryAllocation(TRUE);
  1425.                 Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  1426.  
  1427.                 TRedoCommand* redoCommand = new TRedoCommand;
  1428.                 redoCommand->IRedoCommand(aCommandNumber);
  1429.                 redoCommand->fUseAppleEvent = TRUE;
  1430.                 this->PostCommand(redoCommand);
  1431.                 
  1432.                 TemporaryAllocation(oldTempAlloc);
  1433.                 AllocateObjectsFromPerm(oldObjectPerm);
  1434.             }
  1435.             break;
  1436.  
  1437.         case cClose:
  1438. #if qDebug
  1439.             if (this->WMgrToWindow(FrontWindow()))
  1440.                 ProgramBreak("The frontmost window is a window object but didn't handle the cClose CommandNumber, your TWindow subclass probably forgot to call Inherited::DoMenuCommand!");
  1441. #endif
  1442.  
  1443.             this->CloseToolboxWindow(FrontWindow());// TWindow would have handled the command
  1444.                                                     // before we get here so the window is
  1445.             break;                                    // probably a DA or something
  1446.  
  1447.         default:
  1448.             Inherited::DoMenuCommand(aCommandNumber);
  1449.             break;
  1450.     }
  1451. } // TDispatcher::DoMenuCommand 
  1452.  
  1453. //----------------------------------------------------------------------------------------
  1454. // TDispatcher::DoSetupMenus: 
  1455. //----------------------------------------------------------------------------------------
  1456. #pragma segment MAApplicationRes
  1457.  
  1458. void TDispatcher::DoSetupMenus()
  1459. {
  1460.     Inherited::DoSetupMenus();
  1461.  
  1462.     gMenuBarManager->SetPreferredMenuBarID(fDisplayedMenus);
  1463.     gMenuBarManager->SetPreferredHierMenuBarID(fMBarHierarchical);
  1464.  
  1465.     Boolean lowSpace = MemSpaceIsLow();
  1466.  
  1467.     Enable(-(mApple << 8), TRUE);    // allow the whole menu
  1468.  
  1469.     WindowRef aWindowPtr = FrontWindow();
  1470.     if ((aWindowPtr) && (this->WMgrToWindow(aWindowPtr) == NULL))
  1471.         // window objects will take care of themselves, but we take care of the indigent.
  1472.         Enable(cClose, GetWindowGoAwayFlag(aWindowPtr));
  1473. } // TDispatcher::DoSetupMenus 
  1474.  
  1475. //----------------------------------------------------------------------------------------
  1476. // TDispatcher::DoMakeDependencySpace: 
  1477. //----------------------------------------------------------------------------------------
  1478. #pragma segment MAInit
  1479.  
  1480. void TDispatcher::DoMakeDependencySpace()
  1481. {
  1482.     TSimpleDependencySpace* aDependencySpace = NULL;
  1483.     
  1484.     aDependencySpace = new TSimpleDependencySpace;
  1485.     aDependencySpace->ISimpleDependencySpace();
  1486.     
  1487.     gMacAppDependencies = aDependencySpace;
  1488. }
  1489.  
  1490. //----------------------------------------------------------------------------------------
  1491. // TDispatcher::GetDefaultCursorRegion: Make the region the desktop less the active
  1492. // window, and any first click windows. The current mouse location is added in
  1493. // TDispatcher::TrackCursor.
  1494. //----------------------------------------------------------------------------------------
  1495. #pragma segment MAApplicationRes
  1496.  
  1497. void TDispatcher::GetDefaultCursorRegion(CPoint /* globalMouse */,
  1498.                                           RgnHandle cursorRegion)
  1499. {
  1500.     // Start off with the "desktop region" 
  1501.     GetDeskTopRegion(cursorRegion);
  1502.  
  1503.     // Remove the content of all windows for which TestWindow returns true 
  1504.     CTemporaryRegion windowContent;
  1505.  
  1506.     CWMgrIterator iter;
  1507.  
  1508.     for (WindowRef aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow())
  1509.     {
  1510.         TWindow * aWindow = this->WMgrToWindow(aWinPtr);
  1511.  
  1512.         if (aWindow && aWindow->IsShown()
  1513. #if !qDrag
  1514.             && aWindow->HandlesCursor()
  1515. #endif
  1516.             && aWindow->Focus())
  1517.         {
  1518.             aWindow->GetVisibleRegion(windowContent);
  1519.             
  1520.             // Convert the content to global coordinates. We focused on the window because
  1521.             // the content is in the coordinates of the current port
  1522.             aWindow->LocalToSuperRegion(windowContent);
  1523.  
  1524.             // Remove the visRgn from the cursor region 
  1525.             DiffRgn(cursorRegion, windowContent, cursorRegion);
  1526.         }
  1527.     }
  1528. } // TDispatcher::GetDefaultCursorRegion 
  1529.  
  1530. //----------------------------------------------------------------------------------------
  1531. // TDispatcher::InstallHelpMenuItems: 
  1532. //----------------------------------------------------------------------------------------
  1533. #pragma segment MAApplicationRes
  1534. void TDispatcher::InstallHelpMenuItems()
  1535. {
  1536.     // abstract method; override to install your help menu item(s).  Use
  1537.     // gMenuBarManager->AddHelpMenuItem( "^0 Help", kYourHelpCommandNumber );
  1538. } // TDispatcher::InstallHelpMenuItems 
  1539.  
  1540. //----------------------------------------------------------------------------------------
  1541. // TDispatcher::GetDefaultHelpRegion: Make the region the desktop less the active window,
  1542. // and any first click windows. The current mouse location is added in
  1543. // TDispatcher::TrackHelp.
  1544. //----------------------------------------------------------------------------------------
  1545. void TDispatcher::GetDefaultHelpRegion(CPoint /* globalMouse */,
  1546.                                         RgnHandle helpRegion)
  1547. {
  1548.     // Start off with the "desktop region" 
  1549.     GetDeskTopRegion(helpRegion);
  1550.  
  1551.     // Remove the content of all windows for which TestWindow returns true 
  1552.     CTemporaryRegion windowContent;
  1553.  
  1554.     CWMgrIterator iter;
  1555.  
  1556.     for (WindowRef aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow())
  1557.     {
  1558.         TWindow * aWindow = this->WMgrToWindow(aWinPtr);
  1559.  
  1560.         if (aWindow && (aWindow->IsShown() && aWindow->HandlesHelp()) && aWindow->Focus())
  1561.         {
  1562.             aWindow->GetVisibleRegion(windowContent);
  1563.             
  1564.             // Convert the content to global coordinates. We focused on the window because
  1565.             // the content is in the coordinates of the current port
  1566.             aWindow->LocalToSuperRegion(windowContent);
  1567.  
  1568.             // Remove the visRgn from the cursor region 
  1569.             DiffRgn(helpRegion, windowContent, helpRegion);
  1570.         }
  1571.     }
  1572. } // TDispatcher::GetDefaultHelpRegion 
  1573.  
  1574. //----------------------------------------------------------------------------------------
  1575. // TDispatcher::GetHelpParameters: 
  1576. //----------------------------------------------------------------------------------------
  1577. #pragma segment MAApplicationRes
  1578.  
  1579. void TDispatcher::GetHelpParameters(ResNumber helpResource,
  1580.                                      short helpIndex,
  1581.                                      short helpState,
  1582.                                      HMMessageRecord& helpMessage,
  1583.                                      CPoint& localQDTip,
  1584.                                      CRect& localQDRect,
  1585.                                      short& balloonVariant)
  1586. {
  1587.     MAVolatileInit(short, oldResFile, MACurResFile());
  1588.  
  1589.     FailInfo fi;
  1590.     Try(fi)
  1591.     {
  1592.         MAUseResFile(gApplicationRefNum);
  1593.         
  1594.         unsigned long options;
  1595.         short theProc;
  1596.         short count;
  1597.         FailOSErr(HMGetIndHelpMsg(kHMDialogResType, 
  1598.                                 helpResource, helpIndex, helpState,
  1599.                                 &options, localQDTip, localQDRect, &theProc,
  1600.                                 &balloonVariant, &helpMessage, &count));
  1601.         fi.Success();
  1602.     }
  1603.     else
  1604.     {
  1605.         MAUseResFile(oldResFile);
  1606.         fi.ReSignal();
  1607.     }
  1608.     MAUseResFile(oldResFile);
  1609. } // TDispatcher::GetHelpParameters 
  1610.  
  1611. //----------------------------------------------------------------------------------------
  1612. // TDispatcher::GetSleepRegion: 
  1613. //----------------------------------------------------------------------------------------
  1614. #pragma segment MAApplicationRes
  1615.  
  1616. RgnHandle TDispatcher::GetSleepRegion()
  1617. {
  1618.     if (this->IsFrontProcess())
  1619.     {
  1620.         // Compute based on where the mouse is right NOW 
  1621.         CPoint globalMouse;
  1622.  
  1623.         GetMouse(globalMouse);
  1624.         LocalToGlobal(globalMouse);
  1625.  
  1626.         Boolean isSleepInvalid = FALSE;
  1627.  
  1628.         // The help region is computed before the cursor rgn so that
  1629.         // the cursor region excludes the balloon shape
  1630.         if ((this->IsHelpRgnInvalid()) && (this->IsHelpEnabled()))
  1631.         {
  1632.             this->TrackHelp(globalMouse);
  1633.             isSleepInvalid = TRUE;
  1634.         }
  1635.  
  1636.         if (this->IsCursorRgnInvalid())
  1637.         {
  1638.             this->TrackCursor(globalMouse);
  1639.             isSleepInvalid = TRUE;
  1640.         }
  1641.  
  1642.         if (isSleepInvalid)
  1643.             if (this->IsHelpEnabled())
  1644.                 SectRgn(fCursorRegion, fHelpRegion, fSleepRegion);
  1645.             else
  1646.                 CopyRgn(fCursorRegion, fSleepRegion);
  1647.  
  1648.         // Ensure that the sleep region contains the mouse. 
  1649.         TView::PtAndRgn(globalMouse, fSleepRegion);
  1650.  
  1651.         return fSleepRegion;
  1652.     }
  1653.     else
  1654.     return NULL;
  1655. } // TDispatcher::GetSleepRegion 
  1656.  
  1657. //----------------------------------------------------------------------------------------
  1658. // TDispatcher::GetEvent: 
  1659. //----------------------------------------------------------------------------------------
  1660. #pragma segment MAApplicationRes
  1661.  
  1662. TToolboxEvent* TDispatcher::GetEvent(short eventMask,
  1663.                                       long sleep,
  1664.                                       RgnHandle sleepRegion)
  1665. {
  1666.     TToolboxEvent * returnEvent = NULL;
  1667.  
  1668.     if (--gRsrcCheck <= 0)
  1669.     {
  1670.         CheckRsrcUsage();
  1671.         gRsrcCheck = kRsrcCheckInterval;
  1672.     }
  1673.  
  1674. #if qDebug
  1675.     if (gIntenseDebugging && gReportEvent)
  1676.     {
  1677.         fprintf(stderr, "WaitNextEvent: sleep=0%d", sleep);
  1678.         // faceless driver bug fixed in MF 7.0 
  1679.         if (sleepRegion == NULL)
  1680.             fprintf(stderr, ", sleep region=NULL");
  1681.         else
  1682.         {
  1683.             CRect bBox((*sleepRegion)->rgnBBox);
  1684.             fprintf(stderr, ", sleep region = %s", (const char*) bBox);
  1685.         }
  1686.         fprintf(stderr, "\n");
  1687.  
  1688.     }
  1689.  
  1690.     if (gShowCursorRegion || gShowHelpRegion || gShowSleepRegion)
  1691.     {
  1692.         if (gShowCursorRegion)
  1693.             ShowGlobalRegion(fCursorRegion);
  1694.         
  1695.         if (gShowHelpRegion)
  1696.             ShowGlobalRegion(fHelpRegion);
  1697.         
  1698.         if (gShowSleepRegion)
  1699.             ShowGlobalRegion(fSleepRegion);
  1700.         
  1701.         sleep = 60;
  1702.     }
  1703.  
  1704. #endif // qDebug
  1705.  
  1706.     // If we are in a nested event level than don't turn off the busy cursor since we are
  1707.     // probably in the middle of an idle or filter proc and don't want to turn on and off
  1708.     // the busy cursor each time it gets to service an event.
  1709.     if (fEventLevel <= 1)
  1710.         this->ActivateBusyCursor(FALSE);            // Turn off busy cursor while we're away.
  1711.  
  1712. #if qPerform
  1713.     Boolean oldSetting = PerfMonitorEnabled();
  1714. #endif
  1715.  
  1716.     // SystemEvents aren't queued and will be lost if not retrieved when available. So we
  1717.     // ensure here that they are always retrieved by adding osMask.
  1718.     EventRecord anEvent;
  1719.     if (WaitNextEvent(eventMask | osMask, &anEvent, sleep, sleepRegion))
  1720.     {
  1721. // MWERKS you can remove the following 3 lines if you always send debug messages to your debugger
  1722. // instead of to SIOUX
  1723. #if defined(__MWERKS__) && (qDebug || qTheDebugger)
  1724.         if (!CWDebugHandleOneEvent(&anEvent))
  1725. #endif
  1726.         {
  1727.             Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  1728.             returnEvent = new TToolboxEvent;
  1729.             AllocateObjectsFromPerm(oldObjectPerm);
  1730.             if (returnEvent->IToolboxEvent(this, anEvent))
  1731.             {
  1732.                 // The event was part of a pair used to input 16 bit characters
  1733.                 // Retrieve the second half of the pair immediately.
  1734.                 EventRecord secondaryEvent;
  1735.                 if (GetOSEvent(keyDownMask | keyUpMask | autoKeyMask, &secondaryEvent))
  1736.                     returnEvent->AddSecondaryKeyEvent(secondaryEvent);
  1737.             }
  1738.         }
  1739.     }
  1740.  
  1741. #if qPerform
  1742.     EnablePerfMonitor(oldSetting);
  1743. #endif
  1744.  
  1745.     if (this->IsFrontProcess())                 // If we're not in the background, then 
  1746.         this->ActivateBusyCursor(TRUE);            // …enable the busy cursor mechanism. 
  1747.  
  1748.     return returnEvent;
  1749. } // TDispatcher::GetEvent 
  1750.  
  1751. //----------------------------------------------------------------------------------------
  1752. // TDispatcher::GetFrontWindow: 
  1753. //----------------------------------------------------------------------------------------
  1754. #pragma segment MAApplicationRes
  1755.  
  1756. TWindow* TDispatcher::GetFrontWindow()
  1757. {
  1758.     CWMgrIterator iter;
  1759.  
  1760.     for (WindowRef aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow())
  1761.     {
  1762.         TWindow * aWindow = this->WMgrToWindow(aWinPtr);
  1763.  
  1764.         if ((aWindow) && (aWindow->IsShown()) && (!aWindow->fFloats))
  1765.             return aWindow;
  1766.     }
  1767.     return NULL;
  1768. } // TDispatcher::GetFrontWindow 
  1769.  
  1770. //----------------------------------------------------------------------------------------
  1771. // TDispatcher::GetActiveWindow: 
  1772. //----------------------------------------------------------------------------------------
  1773. #pragma segment MAApplicationRes
  1774.  
  1775. TWindow* TDispatcher::GetActiveWindow(Boolean floatersAreOkay)
  1776. {
  1777.     CWMgrIterator iter;
  1778.  
  1779.     for (WindowRef aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow())
  1780.     {
  1781.         TWindow * aWindow = this->WMgrToWindow(aWinPtr);
  1782.  
  1783.         if ((aWindow) && (aWindow->IsShown()) && (aWindow->IsActive()))
  1784.         {
  1785.             if (aWindow->fFloats)
  1786.             {
  1787.                 if (floatersAreOkay)
  1788.                     return aWindow;
  1789.             }
  1790.             else
  1791.                 return aWindow;
  1792.         }
  1793.     }
  1794.     return NULL;
  1795. } // TDispatcher::GetActiveWindow 
  1796.  
  1797. //----------------------------------------------------------------------------------------
  1798. // TDispatcher::RetrieveAnEvent: 
  1799. //----------------------------------------------------------------------------------------
  1800. #pragma segment MAApplicationRes
  1801.  
  1802. TEvent* TDispatcher::RetrieveAnEvent() // override
  1803. {
  1804.     TEvent* returnEvent = NULL;
  1805.  
  1806.     // Higher priority events are at the end of the list.
  1807.     CEventListIterator iter(fEventList);
  1808.     for (TEvent* itsEvent = iter.FirstEvent(); iter.More(); itsEvent = iter.NextEvent())
  1809.     {
  1810.         if (itsEvent->IsReadyToExecute())
  1811.         {
  1812.             returnEvent = itsEvent;
  1813.             break;
  1814.         }
  1815.     }
  1816.  
  1817.     RemoveEvent(returnEvent);
  1818.  
  1819.     return returnEvent;
  1820. } // TDispatcher::RetrieveAnEvent 
  1821.  
  1822. //----------------------------------------------------------------------------------------
  1823. // TDispatcher::RemoveEvent: 
  1824. //----------------------------------------------------------------------------------------
  1825. #pragma segment MAApplicationRes
  1826.  
  1827. void TDispatcher::RemoveEvent(TEvent* event)
  1828. {
  1829.     if ((event != NULL) && !event->IsRecurring() && (fEventList != NULL))
  1830.         fEventList->Delete(event);
  1831. }
  1832.  
  1833. //----------------------------------------------------------------------------------------
  1834. // TDispatcher::NewToolboxWindow: 
  1835. //----------------------------------------------------------------------------------------
  1836. #pragma segment MAOpen
  1837.  
  1838. #if PRAGMA_ALIGN_SUPPORTED
  1839. #pragma options align=mac68k
  1840. #endif
  1841.  
  1842. struct WINDTemplate
  1843. {
  1844.     CRect bounds;
  1845.     short procID;
  1846.     Boolean visible;
  1847.     Boolean filler1;
  1848.     Boolean goAway;
  1849.     Boolean filler2;
  1850.     long refcon;
  1851.     short itemsID;                            // only for DLOG resource 
  1852. };
  1853. #if PRAGMA_ALIGN_SUPPORTED
  1854. #pragma options align=reset
  1855. #endif
  1856.  
  1857. typedef struct WINDTemplate WINDTemplate;
  1858. typedef WINDTemplate *WINDTemplatePtr, **WINDTemplateHandle;
  1859.  
  1860. WindowRef TDispatcher::NewToolboxWindow(Ptr storage,
  1861.                                          short rsrcId,
  1862.                                          Boolean& isResizable,
  1863.                                          Boolean& isClosable)
  1864. {
  1865.     // We force INVISIBLE in the WIND definition so the screen won't flash. 
  1866.     WindowRef aWMgrWindow;
  1867.     WINDTemplateHandle templateHandle;
  1868.  
  1869.     // Even though the window is permanent, we allocate it under a temporary flag so that the
  1870.     // maximum memory is available. Quickdraw can blow up if it can't allocate a grafPort.
  1871.     MAVolatileInit(Boolean, oldPerm, PermAllocation(FALSE));
  1872.  
  1873.     FailInfo fi;
  1874.     Try(fi)
  1875.     {
  1876.         templateHandle = (WINDTemplateHandle)GetResource('WIND', rsrcId);
  1877.         FailNILResource((Handle)templateHandle);
  1878.         MoveHHi((Handle)templateHandle);        // in case it is locked by the ROM 
  1879.  
  1880.         WINDTemplate & templateData = **templateHandle;
  1881.         templateData.visible = FALSE;
  1882.         isClosable = templateData.goAway;
  1883.         isResizable = ((templateData.procID == documentProc) || (templateData.procID == zoomDocProc)
  1884.         || (((templateData.procID & 0xFFF0) == kSystem75_kWindoidWDEF) && ((templateData.procID & 0x000F) & kSystem75_hasGrow)) 
  1885.         || (((templateData.procID & 0xFFF0) == kSystem75AndLess_kWindoidWDEF) && ((templateData.procID & 0x000F) & kSystem75_hasGrow))
  1886. #if qUseOldFloatingWDEF
  1887.         || (((templateData.procID & 0xFFF0) == kWindoidWDEF) && !((templateData.procID & 0x000F) & kWindoidNotResizable)) 
  1888. #endif
  1889.         );
  1890.         // If your own defProc is resizable, too, then after the call on NewToolboxWindow, set
  1891.         // isResizable true 
  1892.         
  1893.         WindowRef putWindowBehind = TWindow::GetLastFloatingWindowPtr();
  1894.         if (putWindowBehind == NULL)
  1895.             putWindowBehind = (WindowRef) -1;
  1896.         
  1897.         if (qNeedsColorQD || HasColorQD())
  1898.             aWMgrWindow = (WindowRef)(GetNewCWindow(rsrcId, (Ptr)(storage), putWindowBehind));
  1899.         else
  1900.             aWMgrWindow = GetNewWindow(rsrcId, (Ptr)(storage), putWindowBehind);
  1901.  
  1902.         FailNIL(aWMgrWindow);
  1903.         oldPerm = PermAllocation(oldPerm);
  1904.         fi.Success();
  1905.     }
  1906.     else // Recover. Don't need the failure handler since we've set the perm allocation flag back.
  1907.     {
  1908.         // Make sure the perm allocation flag is set back to what it was
  1909.         // when we entered NewToolboxWindow.
  1910.         oldPerm = PermAllocation(oldPerm);
  1911.         fi.ReSignal();
  1912.     }
  1913.  
  1914.     // Now we must make sure that the code reserve is still intact.
  1915.     if (!CheckReserve())
  1916.     {
  1917.         aWMgrWindow = TWindow::FreeIfWMgrWindow(aWMgrWindow, storage == NULL);
  1918.  
  1919.         Failure(memFullErr, 0);
  1920.     }
  1921.  
  1922.     return aWMgrWindow;
  1923. } // TDispatcher::NewToolboxWindow 
  1924.  
  1925. //----------------------------------------------------------------------------------------
  1926. // TDispatcher::GetTarget: 
  1927. //----------------------------------------------------------------------------------------
  1928. #pragma segment MAApplicationRes
  1929.  
  1930. TEventHandler* TDispatcher::GetTarget()
  1931. {
  1932.     return fTarget;
  1933. } // TDispatcher::GetTarget 
  1934.  
  1935. //----------------------------------------------------------------------------------------
  1936. // TDispatcher::HandleActivateEvent: 
  1937. //----------------------------------------------------------------------------------------
  1938. #pragma segment MAApplicationRes
  1939.  
  1940. void TDispatcher::HandleActivateEvent(TToolboxEvent* event)
  1941. {
  1942.     TWindow * aWindow = this->WMgrToWindow((WindowRef)(event->fEventRecord.message));
  1943.     if (aWindow)
  1944.     {
  1945.         Boolean activate = ((event->fEventRecord.modifiers) & activeFlag) != 0;
  1946.         if (aWindow->fFloats)                                // ignore floaters
  1947.         {
  1948.             TWindow* frontWindow = this->GetFrontWindow();    // find frontmost non-floating window
  1949.             if (frontWindow)
  1950.             {
  1951.                 aWindow = frontWindow;                        // (de)activate it instead of the floater
  1952.                 HiliteWindow(aWindow->fWMgrWindow, activate);
  1953.             }
  1954.         }
  1955.         aWindow->Activate(activate);
  1956.     }
  1957.     else
  1958.         this->HandleAlienEvent(event);
  1959. } // TDispatcher::HandleActivateEvent 
  1960.  
  1961. //----------------------------------------------------------------------------------------
  1962. // TDispatcher::HandleAlienEvent: 
  1963. //----------------------------------------------------------------------------------------
  1964. #pragma segment MAApplicationRes
  1965.  
  1966. void TDispatcher::HandleAlienEvent(TToolboxEvent* event)
  1967. {
  1968.     CHandlerIterator iter(fHeadCohandler);
  1969.  
  1970.     for (TEventHandler * aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler())
  1971.         if (aHandler->DoCoHandlerEvent(event))
  1972.             break;
  1973. } // TDispatcher::HandleAlienEvent 
  1974.  
  1975. //----------------------------------------------------------------------------------------
  1976. // TDispatcher::HandleDiskEvent: 
  1977. //----------------------------------------------------------------------------------------
  1978. #pragma segment MADoCommand
  1979.  
  1980. void TDispatcher::HandleDiskEvent(TToolboxEvent* event)
  1981. {
  1982.     if (HiWord(event->fEventRecord.message) != noErr)
  1983.     {
  1984.         short err = DIBadMount(CPoint(112, 80), event->fEventRecord.message);
  1985. #if qDebugMsg
  1986.         if (err != noErr)
  1987.             fprintf(stderr, "error from DIBadMount is %d\n", err);
  1988. #endif
  1989.  
  1990.     }
  1991. } // TDispatcher::HandleDiskEvent 
  1992.  
  1993. //----------------------------------------------------------------------------------------
  1994. // TDispatcher::DoToolboxEvent: 
  1995. //----------------------------------------------------------------------------------------
  1996. #pragma segment MAApplicationRes
  1997.  
  1998. void TDispatcher::DoToolboxEvent(TToolboxEvent* event)
  1999. {
  2000. #if qDebug
  2001.     if (gReportEvent && event)
  2002.         event->ReportEvent();
  2003. #endif
  2004.     
  2005.     this->DispatchEvent(event);
  2006. } // TDispatcher::DoToolboxEvent 
  2007.  
  2008. //----------------------------------------------------------------------------------------
  2009. // TDispatcher::HandleHighLevelEvent: Assume that the high level event received was an
  2010. // Apple Event and process it. This will dispatch to us via MAGeneralDispatch.
  2011. //----------------------------------------------------------------------------------------
  2012. #pragma segment MAApplicationRes
  2013.  
  2014. void TDispatcher::HandleHighLevelEvent(TToolboxEvent* event)
  2015. {
  2016.     this->SetupTheMenus();                        // Make sure that the menus are setup
  2017.     // correctly before we handle the event
  2018.     EventRecord anEventRecord = event->fEventRecord;
  2019.  
  2020.     OSErr theErr = AEProcessAppleEvent(&anEventRecord);
  2021. } // TDispatcher::HandleHighLevelEvent 
  2022.  
  2023. //----------------------------------------------------------------------------------------
  2024. // TDispatcher::HandleKeyDownEvent: 
  2025. //----------------------------------------------------------------------------------------
  2026. #pragma segment MAApplicationRes
  2027.  
  2028. void TDispatcher::HandleKeyDownEvent(TToolboxEvent* event)
  2029. {
  2030.     this->GetTarget()->KeyEventToComponents(event);// Find out what keys were _REALLY_ pressed 
  2031.  
  2032.     if (event->IsCommandKeyPressed())
  2033.         this->GetTarget()->HandleCommandKey(event);
  2034.     else
  2035.         this->GetTarget()->HandleKeyCommand(event);
  2036. } // TDispatcher::HandleKeyDownEvent 
  2037.  
  2038. //----------------------------------------------------------------------------------------
  2039. // TDispatcher::HandleKeyUpEvent: 
  2040. //----------------------------------------------------------------------------------------
  2041. #pragma segment MAApplicationRes
  2042.  
  2043. void TDispatcher::HandleKeyUpEvent(TToolboxEvent* event)
  2044. {
  2045.     // We don't think KeyUp events should affect the menus.
  2046.     event->fAffectsMenus = FALSE;
  2047.     
  2048.     this->GetTarget()->KeyEventToComponents(event);// Find out what keys were _REALLY_ released 
  2049.  
  2050.     this->GetTarget()->HandleKeyUp(event);
  2051. } // TDispatcher::HandleKeyUpEvent 
  2052.  
  2053. //----------------------------------------------------------------------------------------
  2054. // TDispatcher::HandleMouseDown: 
  2055. //----------------------------------------------------------------------------------------
  2056. #pragma segment MAApplicationRes
  2057.  
  2058. void TDispatcher::HandleMouseDown(TToolboxEvent* event)
  2059. {
  2060.     WindowRef aWMgrWindow;
  2061.  
  2062.     short whereMouseDown = FindWindow(event->fEventRecord.where, &aWMgrWindow);
  2063.     event->fClickCount = this->CountClicks(event, whereMouseDown);
  2064.  
  2065.     TWindow * aWindow = this->WMgrToWindow(aWMgrWindow);
  2066.  
  2067. #if qContainer
  2068.     Boolean proceed = TRUE;
  2069.     
  2070.     if (gContainerLib)
  2071.     {
  2072.         if (whereMouseDown != inMenuBar)
  2073.         {
  2074.             CAEventInfo eventInfo;
  2075.             Boolean proceed = !CADispatchEvent(&event->fEventRecords[0], &eventInfo);
  2076.             if (event->fDoubleEvent)
  2077.                 proceed = !CADispatchEvent(&event->fEventRecords[1], &eventInfo);
  2078.         }
  2079.     }
  2080. #endif
  2081.     
  2082.     if ((whereMouseDown != inMenuBar) && this->InModalState() && (aWindow != (this->GetActiveWindow(kNoFloaters))))
  2083.     {
  2084.         //
  2085.         // Allow command drag of behind windows
  2086.         //
  2087.         if ((whereMouseDown != inDrag) || !event->IsCommandKeyPressed())
  2088.         {
  2089.             this->Beep(2);
  2090.             return;                                // exit(HandleMouseDown);
  2091.         }
  2092.     }
  2093.  
  2094. #if qContainer
  2095.     if (proceed)
  2096. #endif
  2097.     {
  2098.         switch (whereMouseDown)
  2099.         {
  2100.             case inMenuBar:
  2101.                 {    // 3.5
  2102.                     this->SetupTheMenus();                // gives application a chance to setup individual menu items
  2103.                     SetCursor(&(qd.arrow));
  2104.                     long menuItem = MenuSelect(event->fEventRecord.where);
  2105.                     this->DispatchMenuEvent(event, menuItem);
  2106.                 }
  2107.                 break;
  2108.     
  2109.             case inSysWindow:
  2110.                 {
  2111.                     EventRecord anEventRecord = event->fEventRecord;
  2112.                     SystemClick(&anEventRecord, (WindowPtr)aWMgrWindow);
  2113.                 }
  2114.                 break;
  2115.     
  2116.             default:                                // if a MacApp window was associated with the WindowRef then let the window object decide
  2117.                 // what to do with the mouse click
  2118.                 if (aWindow)
  2119.                 {
  2120.                     if (aWindow->Focus())            // if we can't focus, we're in trouble 
  2121.                     {
  2122.                         VPoint theMouse(event->fEventRecord.where);
  2123.                         aWindow->SuperToLocal(theMouse);
  2124.                         aWindow->HandleMouseDown(theMouse, event, gStdHysteresis);
  2125.                     }
  2126. #if qDebug
  2127.                     else
  2128.                         ProgramBreak("In TDispatcher::HandleMouseDown: couldn't focus on a window object!");
  2129. #endif
  2130.                 }
  2131.                 else
  2132.                     this->HandleAlienEvent(event);
  2133.                 break;
  2134.     
  2135.         }
  2136.     }    // 3.5
  2137.     fLastUpTime = TickCount();                    // Because the toolbox often eats mouseUpEvents remember the time on the way out for
  2138.     // double/ triple detection.
  2139. } // TDispatcher::HandleMouseDown 
  2140.  
  2141. //----------------------------------------------------------------------------------------
  2142. // TDispatcher::HandleMouseUp: 
  2143. //----------------------------------------------------------------------------------------
  2144. #pragma segment MAApplicationRes
  2145.  
  2146. void TDispatcher::HandleMouseUp(TToolboxEvent* event)
  2147. {
  2148.     // now we _Really_ know what the last mouse up time is.
  2149.     // Remember time of last mouse up, in order to detect double/triple (multiple) clicks 
  2150.     fLastUpTime = event->fEventRecord.when;
  2151.  
  2152.     WindowRef aWMgrWindow;
  2153.     short whereMouseDown = FindWindow(event->fEventRecord.where, &aWMgrWindow);
  2154.  
  2155.     switch (whereMouseDown)
  2156.     {
  2157.         case inMenuBar:
  2158.             break;
  2159.  
  2160.         case inSysWindow:
  2161.             break;
  2162.  
  2163.         default:                                // if a MacApp window was associated with the WindowRef then let the window object decide
  2164.             {
  2165.                 TWindow * aWindow = this->WMgrToWindow(aWMgrWindow);
  2166.  
  2167.                 // what to do with the mouse click
  2168.                 if (aWindow)
  2169.                 {
  2170.                     if (aWindow->Focus())        // if we can't focus, we're in trouble 
  2171.                     {
  2172.                         VPoint theMouse(event->fEventRecord.where);
  2173.                         aWindow->SuperToLocal(theMouse);
  2174.                         aWindow->HandleMouseUp(theMouse, event, gStdHysteresis);
  2175.                     }
  2176. #if qDebug
  2177.                     else
  2178.                         ProgramBreak("In TDispatcher::HandleMouseUp: couldn't focus on a window object!");
  2179. #endif
  2180.                 }
  2181.                 else
  2182.                     this->HandleAlienEvent(event);
  2183.             }
  2184.             break;
  2185.     }
  2186. } // TDispatcher::HandleMouseUp 
  2187.  
  2188. //----------------------------------------------------------------------------------------
  2189. // TDispatcher::HandleSystemEvent: 
  2190. //----------------------------------------------------------------------------------------
  2191. #pragma segment MAApplicationRes
  2192.  
  2193. void TDispatcher::HandleSystemEvent(TToolboxEvent* event)
  2194. {
  2195.     switch (((unsigned long)(event->fEventRecord.message & osEvtMessageMask)) >> 24)
  2196.     {
  2197.         case suspendResumeMessage:
  2198.             {
  2199.                 Boolean switchingIn = ((event->fEventRecord.message) & resumeFlag) != 0;
  2200.                 Boolean convertClipboard = ((event->fEventRecord.message) & convertClipboardFlag) != 0;
  2201.     
  2202.                 if (switchingIn)
  2203.                 {
  2204.                     // the Proces Manager may have activated the wrong window (if, when
  2205.                     // we suspended earlier, we had non-floating window(s) that hide on suspend
  2206.                     // such as the clipboard) so we augment what it did by activating the
  2207.                     // right one!
  2208.                     if (TWindow::MAFrontWindow() != NULL)
  2209.                         TWindow::MADeactivateWindow(TWindow::MAFrontWindow());
  2210.                     
  2211.                     this->RegainControl(convertClipboard);
  2212.     
  2213.                     TWindow * aWindow = this->GetFrontWindow();
  2214.                     if (aWindow)
  2215.                         TWindow::MAActivateWindow(aWindow->fWMgrWindow);
  2216.                 }
  2217.                 else
  2218.                 {
  2219.                     // When switching out, after having hid windows that get hid on suspend in
  2220.                     // AboutToLoseControl, we need to ensure that our idea about the front
  2221.                     // window and the Process Mgr's idea about the front window are the same.
  2222.                     // (note that we do the second half of the work when we get the resume
  2223.                     // event).
  2224.                     WindowRef theFrontWindow = TWindow::MAFrontWindow();// remember the front window
  2225.     
  2226.                     this->AboutToLoseControl(convertClipboard);// might hide windows…
  2227.     
  2228.                     TWindow * aWindow = this->GetActiveWindow(FALSE);
  2229.                     if (aWindow)
  2230.                         TWindow::MADeactivateWindow(aWindow->fWMgrWindow);
  2231.                 }
  2232.     
  2233.                 this->InvalidateMouseRegions();
  2234.             }
  2235.             break;
  2236.  
  2237.         case mouseMovedMessage:
  2238.             event->fAffectsMenus = FALSE;        // We don't think mouse tracking usually
  2239.                                                 // bothers the menus. We got the mouse
  2240.                                                 // moved event because the mouse strayed
  2241.                                                 // outside of fSleepRegion. It may or may
  2242.                                                 // not have strayed outside of the other
  2243.                                                 // mouse regions. We'll only invalidate
  2244.                                                 // them here (if necessary) because that
  2245.                                                 // way we can defer computing them for as
  2246.                                                 // long as possible.
  2247.             if (!PtInRgn(event->fEventRecord.where, fCursorRegion))
  2248.                 this->InvalidateCursorRgn();
  2249.             if (!PtInRgn(event->fEventRecord.where, fHelpRegion))
  2250.                 this->InvalidateHelpRgn();
  2251.             break;
  2252.  
  2253.         default:
  2254. #if qDebugMsg
  2255.             if (gIntenseDebugging)
  2256.                 fprintf(stderr, "in TDispatcher.HandleSystemEvent: got unrecognized event\n");
  2257. #endif
  2258.             break;
  2259.     }
  2260. } // TDispatcher::HandleSystemEvent 
  2261.  
  2262. //----------------------------------------------------------------------------------------
  2263. // TDispatcher::HandleToolboxEvent: 
  2264. //----------------------------------------------------------------------------------------
  2265. #pragma segment MAApplicationRes
  2266.  
  2267. void TDispatcher::HandleToolboxEvent(TToolboxEvent* event)
  2268. {
  2269.     FailInfo fi;
  2270.     Try(fi)
  2271.     {
  2272.         Boolean proceed = TRUE;
  2273.     
  2274.         TBehavior* aBehavior = this->GetFirstEnabledBehavior();    
  2275.         if (aBehavior)
  2276.             proceed = !aBehavior->DoToolboxEvent(event);
  2277.     
  2278.         if (proceed)
  2279.             this->DoToolboxEvent(event);
  2280.  
  2281.         fi.Success();
  2282.     }
  2283.     else // Recover
  2284.     {
  2285.         this->DidEvent(event);
  2286.         fi.ReSignal();
  2287.     }
  2288.  
  2289.     this->DidEvent(event);
  2290. } // TDispatcher::HandleToolboxEvent 
  2291.  
  2292. //----------------------------------------------------------------------------------------
  2293. // TDispatcher::HandleUpdateEvent: 
  2294. //----------------------------------------------------------------------------------------
  2295. #pragma segment MAApplicationRes
  2296.  
  2297. void TDispatcher::HandleUpdateEvent(TToolboxEvent* event)
  2298. {
  2299.     // We don't think that update events should affect menus.
  2300.     event->fAffectsMenus = FALSE;
  2301.     
  2302.     TWindow * aWindow = this->WMgrToWindow((WindowRef)event->fEventRecord.message);
  2303.     if (aWindow)
  2304.         aWindow->Update();
  2305.     else
  2306.         this->HandleAlienEvent(event);
  2307. } // TDispatcher::HandleUpdateEvent 
  2308.  
  2309. //----------------------------------------------------------------------------------------
  2310. // TDispatcher::Idle: 
  2311. //----------------------------------------------------------------------------------------
  2312. #pragma segment MAApplicationRes
  2313.  
  2314. void TDispatcher::Idle(IdlePhase phase)
  2315. {
  2316.     FailInfo fi;
  2317.     Try(fi)
  2318.     {
  2319.         if (phase == idleBegin)
  2320.         {
  2321.             if (!gInFilter)
  2322.             {
  2323. #if qSegments
  2324.                 if (fEventLevel == 1 /*&& MemSpaceIsLow()*/)        // Don't unload segs if nested event handling
  2325.                     UnloadAllSegments();
  2326. #endif
  2327.                 if (MemSpaceIsLow())
  2328.                     this->SpaceIsLowAlert();
  2329.                 else
  2330.                     fNextSpaceMessage = TickCount();
  2331.             }
  2332.         }
  2333.  
  2334.         else if (phase == idleContinue)
  2335.         {
  2336. #if qAttachable
  2337.             // Give an attached script some idle time
  2338.             IdleOSAScript();
  2339. #endif
  2340. #if qContainer
  2341.             //Give the contained parts, if any, Idle time.
  2342.             EventRecord theEventRecord;
  2343.             theEventRecord.what = nullEvent;
  2344.             theEventRecord.message = nullEvent;
  2345.             theEventRecord.when = TickCount();
  2346.             CAEventInfo eventInfo;
  2347.             Boolean eventHandled = CADispatchEvent(&theEventRecord, &eventInfo);
  2348.             //ignoring if it was handled or not, for now
  2349. #endif
  2350.         }
  2351.  
  2352.  
  2353.         // Create a new block for failure handling
  2354.         {
  2355.             CHandlerIterator iter(fHeadCohandler);
  2356.  
  2357.             for (TEventHandler * aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler())
  2358.                 aHandler->HandleIdle(phase);
  2359.         }
  2360.  
  2361. #if qDebug
  2362.         Assertion(this->GetTarget() != NULL, "GetTarget != NULL");
  2363. #endif
  2364.  
  2365.         // Create a new block for failure handling
  2366.         {
  2367.             CHandlerIterator iter(this->GetTarget());
  2368.  
  2369.             for (TEventHandler * aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler())
  2370.                 aHandler->HandleIdle(phase);
  2371.         }
  2372.  
  2373.         fi.Success();
  2374.     }
  2375.     else // Recover
  2376.     {
  2377. #if qDebugMsg
  2378.         fprintf(stderr, "Idle failed\n");
  2379. #endif
  2380.     }
  2381. } // TDispatcher::Idle 
  2382.  
  2383. //----------------------------------------------------------------------------------------
  2384. // TDispatcher::GetWaitTicks: 
  2385. //----------------------------------------------------------------------------------------
  2386. #pragma segment MAApplicationRes
  2387.  
  2388. long TDispatcher::GetWaitTicks(Boolean allowApplicationToSleep)
  2389. {
  2390.     const short kMaxSleep = 60;                    // max sleep in foreground so MultiFinder
  2391.     // gives time to non-desk accessory drivers
  2392.  
  2393.     long returnValue = 0;
  2394.  
  2395.     if (allowApplicationToSleep)
  2396.     {
  2397.         long compositeTicks = kMaxIdleTime;
  2398.  
  2399.         // Check the cohandler chain first.  Add new block for failure handling
  2400.         {
  2401.             CHandlerIterator iter(fHeadCohandler);
  2402.  
  2403.             for (TEventHandler * aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler())
  2404.                 compositeTicks = MinMax(0, aHandler->NextIdle() - TickCount(), compositeTicks);
  2405.         }
  2406.  
  2407. #if qDebug
  2408.         Assertion(this->GetTarget() != NULL, "GetTarget != NULL");
  2409. #endif
  2410.  
  2411.         // now run through the target chain.  Add new block for failure handling
  2412.         {
  2413.             CHandlerIterator iter(this->GetTarget());
  2414.  
  2415.             for (TEventHandler * aHandler = iter.FirstHandler(); iter.More(); aHandler = iter.NextHandler())
  2416.                 compositeTicks = MinMax(0, aHandler->NextIdle() - TickCount(), compositeTicks);
  2417.         }
  2418.  
  2419.         returnValue = compositeTicks;
  2420.     }
  2421.  
  2422.     return returnValue;
  2423. } // TDispatcher::GetWaitTicks 
  2424.  
  2425. //----------------------------------------------------------------------------------------
  2426. // TDispatcher::InModalState: 
  2427. //----------------------------------------------------------------------------------------
  2428. #pragma segment MAApplicationRes
  2429.  
  2430. Boolean TDispatcher::InModalState()
  2431. {
  2432.     WindowRef aWindowPtr = FrontWindow();
  2433.  
  2434.     // in case the front window is an alert or something 
  2435.     if ((this->WMgrToWindow(aWindowPtr) == NULL) && (aWindowPtr))
  2436.         switch (GetWindowVariant(aWindowPtr))
  2437.         {
  2438.             case dBoxProc:
  2439.             case plainDBox:
  2440.             case altDBoxProc:
  2441.                 return TRUE;
  2442.             default:
  2443.                 return FALSE;
  2444.         }
  2445.     else
  2446.     {
  2447.         TWindow * aWindow = this->GetActiveWindow(kNoFloaters);
  2448.         return (aWindow && aWindow->IsInModalState());
  2449.     }
  2450. } // TDispatcher::InModalState 
  2451.  
  2452. //----------------------------------------------------------------------------------------
  2453. // TDispatcher::InstallCohandler: 
  2454. //----------------------------------------------------------------------------------------
  2455. #pragma segment MANonRes
  2456.  
  2457. void TDispatcher::InstallCohandler(TEventHandler* aCohandler,
  2458.                                     Boolean addIt)
  2459. {
  2460.     if (addIt)
  2461.         fHeadCohandler = aCohandler->AddHandler(fHeadCohandler);
  2462.     else
  2463.         fHeadCohandler = aCohandler->RemoveHandler(fHeadCohandler);
  2464. } // TDispatcher::InstallCohandler 
  2465.  
  2466. //----------------------------------------------------------------------------------------
  2467. // TDispatcher::IsFrontProcess: 
  2468. //----------------------------------------------------------------------------------------
  2469. #pragma segment MAApplicationRes
  2470.  
  2471. Boolean TDispatcher::IsFrontProcess()
  2472. {
  2473.     ProcessSerialNumber aPSN;
  2474.     ProcessSerialNumber applicationPSN;
  2475.     Boolean result;
  2476.  
  2477.     FailOSErr(GetFrontProcess(&aPSN));
  2478.     applicationPSN = fProcessNumber;
  2479.     FailOSErr(SameProcess(&aPSN, &applicationPSN, &result));
  2480.     return result;
  2481. } // TDispatcher::IsFrontProcess 
  2482.  
  2483. //----------------------------------------------------------------------------------------
  2484. // TDispatcher::MakeFrontProcess: 
  2485. //----------------------------------------------------------------------------------------
  2486. #pragma segment MAApplicationRes
  2487.  
  2488. void TDispatcher::MakeFrontProcess()
  2489. {
  2490.     if (!this->IsFrontProcess())
  2491.     {
  2492.         ProcessSerialNumber aPSN = fProcessNumber;
  2493.         FailOSErr(SetFrontProcess(&aPSN));
  2494.     }
  2495. } // TDispatcher::MakeFrontProcess 
  2496.  
  2497. //----------------------------------------------------------------------------------------
  2498. // TDispatcher::WakeProcess: 
  2499. //----------------------------------------------------------------------------------------
  2500. #pragma segment MAApplicationRes
  2501. void TDispatcher::WakeProcess()
  2502. {
  2503.     ProcessSerialNumber aPSN = fProcessNumber;
  2504.     FailOSErr(WakeUpProcess(&aPSN));
  2505. }
  2506.  
  2507. //----------------------------------------------------------------------------------------
  2508. // TDispatcher::IsHelpEnabled: 
  2509. //----------------------------------------------------------------------------------------
  2510. #pragma segment MAApplicationRes
  2511.  
  2512. Boolean TDispatcher::IsHelpEnabled()
  2513. {
  2514.     return HMGetBalloons();
  2515. } // TDispatcher::IsHelpEnabled 
  2516.  
  2517. //----------------------------------------------------------------------------------------
  2518. // TDispatcher::InvalidateMouseRegions: 
  2519. //----------------------------------------------------------------------------------------
  2520. #pragma segment MAApplicationRes
  2521.  
  2522. void TDispatcher::InvalidateMouseRegions()
  2523. {
  2524.     this->InvalidateCursorRgn();
  2525.     this->InvalidateHelpRgn();
  2526. } // TDispatcher::InvalidateMouseRegions 
  2527.  
  2528. //----------------------------------------------------------------------------------------
  2529. // TDispatcher::InvalidateCursorRgn: 
  2530. //----------------------------------------------------------------------------------------
  2531. #pragma segment MAApplicationRes
  2532.  
  2533. void TDispatcher::InvalidateCursorRgn()
  2534. {
  2535.     if (fCursorRegion)
  2536.         SetEmptyRgn(fCursorRegion);                // Make sure it gets changed back 
  2537. } // TDispatcher::InvalidateCursorRgn 
  2538.  
  2539. //----------------------------------------------------------------------------------------
  2540. // TDispatcher::InvalidateHelpRgn: 
  2541. //----------------------------------------------------------------------------------------
  2542. #pragma segment MAApplicationRes
  2543.  
  2544. void TDispatcher::InvalidateHelpRgn()
  2545. {
  2546.     if (fHelpRegion)
  2547.         SetEmptyRgn(fHelpRegion);                // Make sure it gets changed back 
  2548.  
  2549.     if (this->IsFrontProcess() && HMIsBalloon())
  2550.     {
  2551.         OSErr err = HMRemoveBalloon();
  2552.         if (err != hmNoBalloonUp)
  2553.             FailOSErr(err);
  2554.     }
  2555. } // TDispatcher::InvalidateHelpRgn 
  2556.  
  2557. //----------------------------------------------------------------------------------------
  2558. // TDispatcher::InvalidateFocus: 
  2559. //----------------------------------------------------------------------------------------
  2560. #pragma segment MAApplicationRes
  2561.  
  2562. void TDispatcher::InvalidateFocus()
  2563. {
  2564.     if (TView::gFocusedView)
  2565.         TView::gFocusedView->InvalidateFocus();
  2566. } // TDispatcher::InvalidateFocus 
  2567.  
  2568. //----------------------------------------------------------------------------------------
  2569. // TDispatcher::IsCursorRgnInvalid: 
  2570. //----------------------------------------------------------------------------------------
  2571. #pragma segment MAApplicationRes
  2572.  
  2573. Boolean TDispatcher::IsCursorRgnInvalid()
  2574. {
  2575.     // The cursor is normally tracked via MouseMoved events. But for those with special
  2576.     // needs fAlwaysTrackCursor can come to the rescue.
  2577.  
  2578.     return (EmptyRgn(fCursorRegion) || fAlwaysTrackCursor);
  2579. } // TDispatcher::IsCursorRgnInvalid 
  2580.  
  2581. //----------------------------------------------------------------------------------------
  2582. // TDispatcher::IsHelpRgnInvalid: 
  2583. //----------------------------------------------------------------------------------------
  2584. #pragma segment MAApplicationRes
  2585.  
  2586. Boolean TDispatcher::IsHelpRgnInvalid()
  2587. {
  2588.     return EmptyRgn(fHelpRegion);
  2589. } // TDispatcher::IsHelpRgnInvalid 
  2590.  
  2591. //----------------------------------------------------------------------------------------
  2592. // TDispatcher::KeyEventToComponents: 
  2593. //----------------------------------------------------------------------------------------
  2594. #pragma segment MAApplicationRes
  2595.  
  2596. void TDispatcher::KeyEventToComponents(TToolboxEvent* event)
  2597. // See Tech Note #263 for the reason for this abomination 
  2598. {
  2599.     Inherited::KeyEventToComponents(event);        // Get default translation, if any 
  2600.  
  2601.     if ((event->fEventRecord.what == keyDown) || (event->fEventRecord.what == keyUp) || (event->fEventRecord.what == autoKey))
  2602.     {
  2603.         // Now see if the command key is down. If it is, get the correct ASCII translation by
  2604.         // masking the command key out and re-translating because the command key will
  2605.         // mask the shift modifier.
  2606.  
  2607.         if (event->IsCommandKeyPressed())
  2608.         {
  2609.             const short kMaskModifier = 0xFE00;            // need to strip command key from Modifiers 
  2610.             const long kMaskASCII1 = 0x000000FF;            // get key from KeyTranslate return 
  2611.             const long kMaskASCII2 = 0x00FF0000;            // get key from KeyTranslate return 
  2612.             const short kUpKeyMask = 0x0080;
  2613.         
  2614.             int maxCount = event->fDoubleEvent ? 2 : 1;
  2615.             event->fText.Empty();
  2616.  
  2617.             for (int i = 0; i < maxCount; ++i)
  2618.             {
  2619.                 // set the upkey bit so KeyTranslate doesn't do special deadkey processing
  2620.                 // See IM-V pp. 195 
  2621.                 short keyCodeParameter = ((((event->fEventRecords[i].modifiers) & kMaskModifier) | event->fKeyCode) | kUpKeyMask);
  2622.  
  2623.                 // Get the correct keytable pointer. We don't want to grope the system unnecessarily so
  2624.                 // use the script managers improvements if they're there.
  2625.                 Ptr keyTransTable = (Ptr)(GetScriptManagerVariable(smKCHRCache));
  2626.  
  2627.                 UInt32 state = 0;
  2628.                 UInt32 keyInfo = KeyTranslate(keyTransTable, keyCodeParameter, &state);
  2629.  
  2630.                 event->fText[i + 1] = (unsigned char)(((keyInfo) & kMaskASCII1));
  2631.                 // Remember fText is a string, the text starts at [1]
  2632.                 if (event->fText[i + 1] == 0)
  2633.                     event->fText[i + 1] = (unsigned char)((keyInfo & kMaskASCII2) >> 16);
  2634.             }
  2635.         }
  2636.     }
  2637. } // TDispatcher::KeyEventToComponents 
  2638.  
  2639. //----------------------------------------------------------------------------------------
  2640. // TDispatcher::MainEventLoop: 
  2641. //----------------------------------------------------------------------------------------
  2642. #pragma segment MAApplicationRes
  2643. // must be in the main segment 
  2644.  
  2645. void TDispatcher::MainEventLoop()
  2646. {
  2647.     fIdlePhase = idleBegin;
  2648.     while (!fDone)
  2649.         this->PollEvent(kAllowApplicationToSleep);
  2650. } // TDispatcher::MainEventLoop 
  2651.  
  2652. //----------------------------------------------------------------------------------------
  2653. // TDispatcher::DoLaunchClipboard: 
  2654. //----------------------------------------------------------------------------------------
  2655. #pragma segment MAOpen
  2656.  
  2657. void TDispatcher::DoLaunchClipboard()
  2658. {
  2659.     if (gClipboardMgr)
  2660.     {
  2661.         gClipboardMgr->Launch();                // Launch after segments are unloaded
  2662.                                                 // since reading the scrap may be piggy
  2663.     }
  2664. } // TDispatcher::DoLaunchClipboard 
  2665.  
  2666. //----------------------------------------------------------------------------------------
  2667. // TDispatcher::MakeViewForAlienClipboard: 
  2668. //----------------------------------------------------------------------------------------
  2669. #pragma segment MAClipboard
  2670.  
  2671. TView* TDispatcher::MakeViewForAlienClipboard()
  2672. {
  2673.     return NULL;                                // use defaults 
  2674. } // TDispatcher::MakeViewForAlienClipboard 
  2675.  
  2676. //----------------------------------------------------------------------------------------
  2677. // TDispatcher::DispatchMenuEvent: 
  2678. //----------------------------------------------------------------------------------------
  2679. #pragma segment MASelCommand
  2680.  
  2681. #if qContainer
  2682. void TDispatcher::DispatchMenuEvent(TToolboxEvent* event, long menuItem)
  2683. #else
  2684. void TDispatcher::DispatchMenuEvent(TToolboxEvent* /*event*/, long menuItem)
  2685. #endif
  2686. {
  2687. #if qContainer
  2688.     Boolean proceed = TRUE;
  2689.     if (gContainerLib)
  2690.         proceed = !CADispatchMenuEvent(&event->fEventRecords[0], menuItem);
  2691.         if (event->fDoubleEvent)
  2692.             proceed = !CADispatchMenuEvent(&event->fEventRecords[1], menuItem);
  2693.     if (proceed)
  2694. #endif
  2695.         this->MenuEvent(menuItem);
  2696. }
  2697.  
  2698. //----------------------------------------------------------------------------------------
  2699. // TDispatcher::MenuEvent: 
  2700. //----------------------------------------------------------------------------------------
  2701. #pragma segment MASelCommand
  2702.  
  2703. void TDispatcher::MenuEvent(long menuItem)
  2704. {
  2705.     short theMenuNumber = HiWord(menuItem);
  2706.     short theItemNumber = LoWord(menuItem);
  2707.  
  2708.     if (theMenuNumber)
  2709.     {
  2710.         MAVolatileInit(CommandNumber, command, CommandFromMenuItem(theMenuNumber, theItemNumber));
  2711.  
  2712. #if qDebugMsg
  2713.         if (command == cCantUndo)
  2714.         {
  2715.             fprintf(stderr, "Command number %d is reserved for MacApp.\n", cCantUndo);
  2716.             ProgramBreak("Use of reserved command number.");
  2717.         }
  2718.  
  2719.         if (gReportMenuChoices && (command > 0))
  2720.             fprintf(stderr, "Menu Choice Command Number == %d\n", command);
  2721. #endif
  2722.  
  2723.         if ((command < 0) && (theMenuNumber == mApple))
  2724.         {
  2725.             CStr255 deskAccName;
  2726.  
  2727.             GetMenuItemText(MAGetMenuRef(mApple), theItemNumber, deskAccName);
  2728.             this->OpenDeskAccessory(deskAccName);
  2729.         }
  2730.         else if ((command < cEditBase) || (command > cEditLast) || (!SystemEdit((short)(command - cEditBase))))
  2731.         {
  2732.             FailInfo fi;
  2733.             Try(fi)
  2734.             {
  2735.                 if (fSysWindowActive)
  2736.                     this->ActivateBusyCursor(TRUE);
  2737.  
  2738.                 this->GetTarget()->HandleMenuCommand(command);
  2739.  
  2740.                 if (fSysWindowActive)
  2741.                     this->ActivateBusyCursor(FALSE);
  2742.                 fi.Success();
  2743.             }
  2744.             else // Recover
  2745.             {
  2746.                 if (fSysWindowActive)
  2747.                     this->ActivateBusyCursor(FALSE);
  2748.  
  2749.                 FailNewMessage(fi.error, fi.message, BuildMessage((short)command, messageCommandError));
  2750.             }
  2751.         }
  2752.     }
  2753. } // TDispatcher::MenuEvent 
  2754.  
  2755. //----------------------------------------------------------------------------------------
  2756. // TDispatcher::OpenDeskAccessory: 
  2757. //----------------------------------------------------------------------------------------
  2758. void TDispatcher::OpenDeskAccessory(const CStr255& deskAccName)
  2759. {
  2760.     GrafPtr savedPort;
  2761.  
  2762.     GetPort(&savedPort);
  2763.     OpenDeskAcc(deskAccName);
  2764.     SetPort(savedPort);
  2765. } // TDispatcher::OpenDeskAccessory 
  2766.  
  2767. //----------------------------------------------------------------------------------------
  2768. // TDispatcher::ProcessEvent: 
  2769. //----------------------------------------------------------------------------------------
  2770. #pragma segment MAApplicationRes
  2771.  
  2772. void TDispatcher::ProcessEvent(TEvent* event)
  2773. {
  2774. #if qDebug
  2775.     if (!event)
  2776.         ProgramBreak("NULL passed to TDispatcher::ProcessEvent");
  2777.     else if (!IsObject(event))        // since it's possible to have passed in a
  2778.                                     // freed undoable command allocated in a
  2779.                                     // global variable (due to pilot error)
  2780.     {
  2781.         VerboseIsObject(event);
  2782.         ProgramBreak("bogus object passed to TDispatcher::ProcessEvent");
  2783.     }
  2784.     else
  2785.     {
  2786.         if (gIntenseDebugging)
  2787.             fprintf(stderr, "The Event to process: %s\n", event->GetClassName());
  2788.     }
  2789. #endif
  2790.     if (event)
  2791.         event->Process();
  2792. } // TDispatcher::ProcessEvent 
  2793.  
  2794. //----------------------------------------------------------------------------------------
  2795. // TDispatcher::PollEvent: 
  2796. //----------------------------------------------------------------------------------------
  2797. #pragma segment MAApplicationRes
  2798.  
  2799. void TDispatcher::PollEvent(Boolean allowApplicationToSleep)
  2800. {
  2801.     MAVolatileInit(Boolean, didAllowApplicationToSleep, fAllowApplicationToSleep);
  2802.  
  2803.     fAllowApplicationToSleep = allowApplicationToSleep;
  2804.  
  2805.     ++fEventLevel;
  2806.  
  2807. #if qDebugMsg
  2808.     if (!this->GetTarget())
  2809.         ProgramBreak("Serious Error!! in TDispatcher.PollEvent: target == NULL");
  2810. #endif
  2811.  
  2812.     FailInfo fi;
  2813.     Try(fi)
  2814.     {
  2815.         TEvent * retrievedEvent = this->RetrieveAnEvent();
  2816.         if (retrievedEvent)
  2817.             this->ProcessEvent(retrievedEvent);
  2818.  
  2819.         // The desk scrap may have been changed by use of command-X or command-C in desk accessories.
  2820.         if (fSysWindowActive)
  2821.         {
  2822.             gClipboardMgr->CheckDeskScrap();
  2823.             this->InvalidateFocus();
  2824.         }
  2825.  
  2826.         fi.Success();
  2827.         --fEventLevel;
  2828.  
  2829.         if (fEventLevel == 0)
  2830.             gInhibitNestedHandling = FALSE;        // All clear 
  2831.     }
  2832.     else // Recover
  2833.     {
  2834. #if qDebugMsg
  2835.         fprintf(stderr, "\n");                // add a blank line after all the messages from Failure
  2836. #endif
  2837.  
  2838.         fAllowApplicationToSleep = didAllowApplicationToSleep;
  2839.  
  2840.         --fEventLevel;
  2841.         if (fEventLevel == 0)
  2842.         {
  2843.             if (fi.error != noErr)
  2844.             {
  2845. #if qSegments
  2846.                 UnloadAllSegments();
  2847. #endif
  2848.                 this->ShowError(fi.error, fi.message);
  2849.             }
  2850.  
  2851.             InvalidateMenus();
  2852.         }
  2853.         else
  2854.             fi.ReSignal();
  2855.     }
  2856.  
  2857.     fAllowApplicationToSleep = didAllowApplicationToSleep;
  2858. } // TDispatcher::PollEvent 
  2859.  
  2860. //----------------------------------------------------------------------------------------
  2861. // TDispatcher::PollToolboxEvent: 
  2862. //----------------------------------------------------------------------------------------
  2863. #pragma segment MAApplicationRes
  2864.  
  2865. Boolean TDispatcher::PollToolboxEvent(Boolean allowApplicationToSleep)
  2866. {
  2867.     long waitTicks = 0;
  2868.     RgnHandle sleepRegion = NULL;
  2869.  
  2870.     EventRecord theEvent;
  2871.     if (!::OSEventAvail(fMainEventMask, &theEvent))    // We'll only sleep if there aren't any
  2872.                                                 // waiting Events (keystrokes, mousedowns)
  2873.     {
  2874.         this->SetupTheMenus();
  2875.  
  2876.         // ensure that a mouse click or key stroke didn't come in during SetupTheMenus
  2877.         if (!::OSEventAvail(fMainEventMask, &theEvent))
  2878.         {
  2879.             sleepRegion = this->GetSleepRegion();
  2880.  
  2881.             // ensure that a mouse click or key stroke didn't come in during GetSleepRegion
  2882.             if (!::OSEventAvail(fMainEventMask, &theEvent))
  2883.                 waitTicks = this->GetWaitTicks(allowApplicationToSleep);// calc last so it's most accurate 
  2884.             else
  2885.                 sleepRegion = NULL;
  2886.  
  2887. #if qContainer
  2888.             if (gContainerLib)
  2889.                 waitTicks = Min(waitTicks, CAGetSleepTime());
  2890. #endif
  2891.         }
  2892.     }
  2893.  
  2894.     MAHiliteMenu(0);                            // Cleanup any menu titles left hilited.
  2895.                                                 // Done here so titles stay hilited until
  2896.                                                 // synchronous actions are performed.
  2897.     TToolboxEvent * event = this->GetEvent(fMainEventMask, waitTicks, sleepRegion);
  2898.     Boolean gotAnEvent = (event != NULL);
  2899.     if (gotAnEvent)
  2900.     {
  2901.         // GetEvent returned an event (work to do). If we were idling before then we must
  2902.         // keep the calls balanced with an IdleEnd to because we are no longer idling
  2903.         if (fIdlePhase == idleContinue)
  2904.         {
  2905.             this->Idle(idleEnd);
  2906.             fIdlePhase = idleBegin;
  2907.         }
  2908.         
  2909.         // Rather than posting the event where it would have to be sorted and compete with
  2910.         // other commands we will process the command directly.
  2911.         this->ProcessEvent(event);
  2912.  
  2913.         // The desk scrap may have been changed by use of command-X or command-C in desk accessories.
  2914.         if (fSysWindowActive)
  2915.         {
  2916.             gClipboardMgr->CheckDeskScrap();
  2917.             this->InvalidateFocus();
  2918.         }
  2919.     }
  2920.     else                                         // Woke up with no event available. Truly idle
  2921.     {
  2922.         this->Idle(fIdlePhase);
  2923.         fIdlePhase = idleContinue;
  2924.     }
  2925.  
  2926. #if qDebug
  2927.     gErrorParm3 = "?????";                        // to prevent anyone from using old values 
  2928. #endif
  2929.  
  2930.     return gotAnEvent;
  2931. } // TDispatcher::PollToolboxEvent 
  2932.  
  2933. //----------------------------------------------------------------------------------------
  2934. // TDispatcher::PostAnEvent: 
  2935. //----------------------------------------------------------------------------------------
  2936. #pragma segment MAApplicationRes
  2937.  
  2938. void TDispatcher::PostAnEvent(TEvent* event)    // Override
  2939. {
  2940.     FailInfo fi;
  2941.     
  2942.     Try(fi)
  2943.     {
  2944.         if (event->IsReadyToPost())
  2945.             fEventList->Insert(event);        // inserts event ordered the list
  2946.         
  2947.         fi.Success();
  2948.     }
  2949.     else
  2950.     {
  2951.         if (event->ShouldFreeOnCompletion())
  2952.             event = (TEvent *)FreeIfObject(event);
  2953.         fi.ReSignal();
  2954.     }
  2955. } // TDispatcher::PostAnEvent 
  2956.  
  2957. //----------------------------------------------------------------------------------------
  2958. // TDispatcher::PostCommand: 
  2959. //----------------------------------------------------------------------------------------
  2960. #pragma segment MAApplicationRes
  2961.  
  2962. void TDispatcher::PostCommand(TCommand* command)// Override
  2963. {
  2964.     if (command)
  2965.     {
  2966.         if (command->CanBeUndone())
  2967.             TUndoHandler::fgUndoHandler->AddActionToHistory(command, kSingleAction, command->fIdentifier);
  2968.         
  2969.         this->PostAnEvent(command);
  2970.     }
  2971. } // TDispatcher::PostCommand 
  2972.  
  2973.  
  2974. //----------------------------------------------------------------------------------------
  2975. // TDispatcher::DidEvent: 
  2976. //----------------------------------------------------------------------------------------
  2977. #pragma segment MAApplicationRes
  2978.  
  2979. void TDispatcher::DidEvent(TToolboxEvent* event)
  2980. {
  2981.     if (event && event->fAffectsMenus)
  2982.         InvalidateMenus();
  2983.  
  2984.     Boolean perm = PermAllocation(FALSE);
  2985. #if qDebug
  2986.     if (perm)
  2987.         ProgramBreak("The permanent flag was left true.");
  2988. #endif
  2989.  
  2990.     if (event && (event->ShouldFreeOnCompletion()))
  2991.         event = (TToolboxEvent *)FreeIfObject(event);
  2992. } // TDispatcher::DidEvent 
  2993.  
  2994. //----------------------------------------------------------------------------------------
  2995. // TDispatcher::RegainControl: 
  2996. //----------------------------------------------------------------------------------------
  2997. #pragma segment MAApplicationRes
  2998.  
  2999. void TDispatcher::RegainControl(Boolean checkClipboard)
  3000. {
  3001. #if qNeedsVU
  3002.     gClipboardMgr->RegainControl(checkClipboard);
  3003. #endif
  3004.  
  3005.     this->Changed(mRegainControl, this);
  3006.  
  3007.     this->ActivateBusyCursor(TRUE);
  3008.  
  3009.     gClipboardMgr->RegainControl(checkClipboard);
  3010.  
  3011.     // Let all windows know that we're regaining control - e.g. so floaters can show themselves 
  3012.     CWMgrIterator iter;
  3013.     for (WindowRef aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow())
  3014.     {
  3015.         TWindow * aWindow = this->WMgrToWindow(aWinPtr);
  3016.  
  3017.         if (aWindow)
  3018.             aWindow->RegainControl();
  3019.     }
  3020.  
  3021.     CDocumentIterator docIter(this);
  3022.  
  3023.     for (TDocument * aDocument = docIter.FirstDocument(); docIter.More(); aDocument = docIter.NextDocument())
  3024.         aDocument->RegainControl();
  3025.  
  3026. } // TDispatcher::RegainControl 
  3027.  
  3028. //----------------------------------------------------------------------------------------
  3029. // TDispatcher::Run: 
  3030. //----------------------------------------------------------------------------------------
  3031. #pragma segment MAApplicationRes
  3032. // must be in the main segment 
  3033.  
  3034. void TDispatcher::Run()
  3035. {
  3036. #if qSegments
  3037.     UnloadAllSegments();
  3038. #endif
  3039.     FailSpaceIsLow();                    // make sure we have enough memory to continue
  3040.  
  3041.  
  3042.     gInitialized = TRUE;                // was set false at static init time 
  3043.  
  3044.     this->DoLaunchClipboard();
  3045.  
  3046. #if qSegments
  3047.     UnloadAllSegments();
  3048. #endif
  3049.     
  3050.     if (fWantKeyUpEvents)
  3051.         ::SetEventMask(everyEvent);        // allow us to get keyup events too.
  3052.  
  3053.     fEventLevel = 0;                            // Indicate outermost level 
  3054.     this->MainEventLoop();                        // runs until a quit command 
  3055.  
  3056.     this->AboutToLoseControl(TRUE);
  3057.  
  3058.     // See if previous max. resource usage has been exceeded by the termination code and
  3059.     // resources.
  3060.     CheckRsrcUsage();
  3061.  
  3062.     if (TPrintHandler::gPrintHandler) // shut down the printing system
  3063.         TPrintHandler::gPrintHandler->TerminateUPrinting();
  3064.  
  3065.     TView::TerminateUView(); // shut down the view system
  3066.  
  3067.     // We must call CleanupMacApp here; if we wait to fall thru to the end of the main
  3068.     // program, A5 has been invalidated and we can't refer to any globals.
  3069.     CleanupMacApp();
  3070. } // TDispatcher::Run 
  3071.  
  3072. //----------------------------------------------------------------------------------------
  3073. // TDispatcher::GetMainEventMask: 
  3074. //----------------------------------------------------------------------------------------
  3075. #pragma segment MAApplicationRes
  3076.  
  3077. short TDispatcher::GetMainEventMask()
  3078. {
  3079.     return fMainEventMask;
  3080. }
  3081.  
  3082. //----------------------------------------------------------------------------------------
  3083. // TDispatcher::SetMainEventMask: 
  3084. //----------------------------------------------------------------------------------------
  3085. #pragma segment MAApplicationRes
  3086.  
  3087. short TDispatcher::SetMainEventMask(short newMask)
  3088. {
  3089.     short oldMask = fMainEventMask;
  3090.     fMainEventMask = newMask;
  3091.     return oldMask;
  3092. }
  3093.  
  3094. //----------------------------------------------------------------------------------------
  3095. // TDispatcher::SetTarget: 
  3096. //----------------------------------------------------------------------------------------
  3097. #pragma segment MAApplicationRes
  3098.  
  3099. void TDispatcher::SetTarget(TEventHandler* newTarget)
  3100. {
  3101.     if (newTarget == NULL)
  3102.     {
  3103.         newTarget = this;
  3104. #if qDebug
  3105.         ProgramBreak("In TDispatcher.SetTarget…  you're setting the global target to NULL!");
  3106. #endif
  3107.  
  3108.     }
  3109.  
  3110.     if (newTarget != fTarget)
  3111.     {
  3112.         fTarget->ResignedTarget();
  3113.         fTarget = newTarget;
  3114.         fTarget->BecameTarget();
  3115.         this->InvalidateMouseRegions();
  3116.     }
  3117. } // TDispatcher::SetTarget 
  3118.  
  3119. //----------------------------------------------------------------------------------------
  3120. // TDispatcher::SetupUndoRedoMenus: 
  3121. //----------------------------------------------------------------------------------------
  3122. #pragma segment MAApplicationRes
  3123.  
  3124. void TDispatcher::SetupUndoRedoMenus()
  3125. {
  3126.     if (TUndoHandler::fgUndoHandler->AnythingToUndo())
  3127.         Enable(cUndo, TRUE);
  3128.     
  3129.     SetUndoText(TUndoHandler::fgUndoHandler->GetUndoID());
  3130.     
  3131.     if (TUndoHandler::fgUndoHandler->AnythingToRedo())
  3132.         Enable(cRedo, TRUE);
  3133.     
  3134.     SetRedoText(TUndoHandler::fgUndoHandler->GetRedoID());
  3135. }
  3136.  
  3137. //----------------------------------------------------------------------------------------
  3138. // TDispatcher::SetUndoText: 
  3139. //----------------------------------------------------------------------------------------
  3140. #pragma segment MAApplicationRes
  3141.  
  3142. void TDispatcher::SetUndoText(CommandNumber id)
  3143. {
  3144.     if (fUndoCommand != id)
  3145.     {
  3146.         CStr255 undoName;
  3147.         GetUndoRedoText(kShowUndo, id, undoName);
  3148.         SetCommandName(cUndo, undoName);
  3149.         fUndoCommand = id;
  3150.     }
  3151. }
  3152.  
  3153. //----------------------------------------------------------------------------------------
  3154. // TDispatcher::SetRedoText: 
  3155. //----------------------------------------------------------------------------------------
  3156. #pragma segment MAApplicationRes
  3157.  
  3158. void TDispatcher::SetRedoText(CommandNumber id)
  3159. {
  3160.     if (fRedoCommand != id)
  3161.     {
  3162.         CStr255 redoName;
  3163.         GetUndoRedoText(kShowRedo, id, redoName);
  3164.         SetCommandName(cRedo, redoName);
  3165.         fRedoCommand = id;
  3166.     }
  3167. }
  3168.  
  3169. //----------------------------------------------------------------------------------------
  3170. // TDispatcher::SetupTheMenus: 
  3171. //----------------------------------------------------------------------------------------
  3172. #pragma segment MAApplicationRes
  3173.  
  3174. void TDispatcher::SetupTheMenus()
  3175. {
  3176. #if qContainer
  3177.     if(!gHasODFocus)
  3178.         return; //if we don't have the focus, we should not be messing with the menus.
  3179.     else
  3180.         {
  3181. #endif
  3182.             if (this->IsFrontProcess() && (MenusHavePendingUpdate()))
  3183.             {
  3184.                 gMenuBarManager->Reset();                // reset the preferred menubar
  3185.         
  3186.                 PerformMenuSetup(&DoSetupTheMenus, NULL);
  3187.                 
  3188.                 gMenuBarManager->InstallPreferredMenus();
  3189.                 if (MenusHavePendingUpdate())
  3190.                 {
  3191.                     // Add the debugger menu
  3192. #if qDebug || qPerform
  3193.                     AddMenuBar(kMBarDebug, FALSE);
  3194. #endif
  3195.         
  3196.                     // Recurse to get the menus correctly setup
  3197.                     this->SetupTheMenus();
  3198.                 }
  3199.             }
  3200. #if qContainer
  3201.         }
  3202. #endif
  3203. } // TDispatcher::SetupTheMenus 
  3204.  
  3205. //----------------------------------------------------------------------------------------
  3206. // TDispatcher::ShowError: 
  3207. //----------------------------------------------------------------------------------------
  3208. #pragma segment MAError
  3209.  
  3210. void TDispatcher::ShowError(OSErr error, long message)
  3211. {
  3212.     ErrorAlert(error, message);
  3213. } // TDispatcher::ShowError 
  3214.  
  3215. //----------------------------------------------------------------------------------------
  3216. // TDispatcher::SpaceIsLowAlert: 
  3217. //----------------------------------------------------------------------------------------
  3218. #pragma segment MAApplicationRes
  3219.  
  3220. void TDispatcher::SpaceIsLowAlert()
  3221. {
  3222.     // Show 'space is low' alert only after ever fLowSpaceInterval ticks. 
  3223.     if ((fLowSpaceInterval > 0) && this->IsFrontProcess())
  3224.     {
  3225.         if (TickCount() > fNextSpaceMessage)
  3226.         {
  3227.             gInhibitNestedHandling = TRUE;    // Don't tell em again from the alert 
  3228.             StdAlert(phSpaceIsLow);
  3229.             fNextSpaceMessage = TickCount() + fLowSpaceInterval;
  3230.         }
  3231.     }
  3232. } // TDispatcher::SpaceIsLowAlert 
  3233.  
  3234. //----------------------------------------------------------------------------------------
  3235. // TDispatcher::DoSetCursor: 
  3236. //----------------------------------------------------------------------------------------
  3237. #pragma segment MAApplicationRes
  3238.  
  3239. void TDispatcher::DoSetCursor(CPoint globalMouse,
  3240.                                RgnHandle cursorRegion)
  3241. {
  3242.     this->GetDefaultCursorRegion(globalMouse, cursorRegion);
  3243.     SetCursor(&(qd.arrow));
  3244. } // TDispatcher::DoSetCursor 
  3245.  
  3246. //----------------------------------------------------------------------------------------
  3247. // TDispatcher::HandleCursor: 
  3248. //----------------------------------------------------------------------------------------
  3249. #pragma segment MAApplicationRes
  3250.  
  3251. void TDispatcher::HandleCursor(CPoint globalMouse,
  3252.                                 RgnHandle cursorRegion)
  3253. {
  3254.     WindowRef aWMgrWindow;
  3255.     if (FindWindow(globalMouse, &aWMgrWindow) == inContent)
  3256.     {
  3257.         TWindow * cursorWindow = this->WMgrToWindow(aWMgrWindow);
  3258.         if (cursorWindow)
  3259.         {
  3260.             if (gDispatcher->GetFrontWindow() == cursorWindow || !gDispatcher->InModalState())
  3261.             {
  3262.                 if (cursorWindow->HandlesCursor())
  3263.                 {
  3264.                     VPoint windowVPt(globalMouse);
  3265.                     cursorWindow->SuperToLocal(windowVPt);
  3266.                     cursorWindow->HandleCursor(windowVPt, cursorRegion);
  3267.         
  3268.                     // Convert cursor region from window coords to global coords 
  3269.                     cursorWindow->LocalToSuperRegion(cursorRegion);
  3270.                 }
  3271. #if qDrag
  3272.                 else if (HasDragManager())
  3273.                 {
  3274.                     VPoint windowVPt(globalMouse);
  3275.                     cursorWindow->SuperToLocal(windowVPt);
  3276.                     cursorWindow->HandleDragCursor(windowVPt, cursorRegion);
  3277.                     
  3278.                     cursorWindow->LocalToSuperRegion(cursorRegion);
  3279.                 }
  3280. #endif
  3281.                 cursorWindow->Focus();    // leave the window origin and clip set
  3282.                                         // so that external utilities such as
  3283.                                         // English Speech Recognition will find
  3284.                                         // controls unclipped.
  3285.             }
  3286.         }
  3287.     }
  3288. } // TDispatcher::HandleCursor 
  3289.  
  3290. //----------------------------------------------------------------------------------------
  3291. // TDispatcher::TrackCursor: 
  3292. //----------------------------------------------------------------------------------------
  3293. #pragma segment MAApplicationRes
  3294.  
  3295. void TDispatcher::TrackCursor(CPoint globalMouse)
  3296. {
  3297.     FailInfo fi;
  3298.     Try(fi)
  3299.     {
  3300. #if qDebugMsg
  3301.         if (PtInRgn(globalMouse, fCursorRegion))
  3302.         {
  3303.             if (gIntenseDebugging)
  3304.                 fprintf(stderr, "cursor is in cursor region\n");
  3305.         }
  3306. #endif
  3307.     
  3308.         this->InvalidateCursorRgn();
  3309.     
  3310.         // Find out if the cursor is in a window which handles the cursor, and if so, call
  3311.         // HandleCursor to allow a view to claim the cursor, and compute a region
  3312.         this->HandleCursor(*((CPoint *)&globalMouse), fCursorRegion);
  3313.     
  3314.         if (EmptyRgn(fCursorRegion))
  3315.             this->DoSetCursor(globalMouse, fCursorRegion);
  3316.     
  3317.         // Make sure the cursorpoint is included 
  3318.         TView::PtAndRgn(globalMouse, fCursorRegion);
  3319.     
  3320. #if qDebugMsg
  3321.         if (gIntenseDebugging)
  3322.             if (fCursorRegion == NULL)
  3323.                 fprintf(stderr, "fCursorRegion is NULL\n");
  3324. #endif
  3325.     
  3326. #if qDebug
  3327.         if (gIntenseDebugging && !PtInRgn(globalMouse, fCursorRegion))
  3328.         {
  3329.             CRect bBox = (*fCursorRegion)->rgnBBox;
  3330.             fprintf(stderr, "Whoops, cursor region was not correctly calculated.\n");
  3331.             fprintf(stderr, "global cursor = ", (const char*)globalMouse);
  3332.             fprintf(stderr, "  (*fCursorRegion)->rgnBBox = ", (const char*) bBox);
  3333.             fprintf(stderr, "\n");
  3334.             ProgramBreak("The cursor is not in the cursor region at end of TDispatcher.TrackCursor!");
  3335.         }
  3336. #endif
  3337.         fi.Success();
  3338.     }
  3339.     else // Recover
  3340.     {
  3341. #if qDebugMsg
  3342.         fprintf(stderr, "TrackCursor failed\n");
  3343. #endif
  3344.         SetEmptyRgn(fCursorRegion);
  3345.         // don't ReSignal
  3346.     }
  3347. } // TDispatcher::TrackCursor 
  3348.  
  3349. //----------------------------------------------------------------------------------------
  3350. // TDispatcher::DoShowHelp: 
  3351. //----------------------------------------------------------------------------------------
  3352. #pragma segment MAApplicationRes
  3353.  
  3354. void TDispatcher::DoShowHelp(CPoint globalMouse,
  3355.                               RgnHandle helpRegion)
  3356. {
  3357.     if (HMIsBalloon())
  3358.     {
  3359.         OSErr err = HMRemoveBalloon();
  3360.         if (err != hmNoBalloonUp)
  3361.             FailOSErr(err);
  3362.     }
  3363.     this->GetDefaultHelpRegion(globalMouse, helpRegion);
  3364. } // TDispatcher::DoShowHelp 
  3365.  
  3366. //----------------------------------------------------------------------------------------
  3367. // TDispatcher::HandleHelp: 
  3368. //----------------------------------------------------------------------------------------
  3369. #pragma segment MAApplicationRes
  3370.  
  3371. void TDispatcher::HandleHelp(CPoint globalMouse,
  3372.                               RgnHandle helpRegion)
  3373. {
  3374.     WindowRef aWMgrWindow;
  3375.     if (FindWindow(globalMouse, &aWMgrWindow) == inContent)
  3376.     {
  3377.         TWindow * helpWindow = this->WMgrToWindow(aWMgrWindow);
  3378.         if ((helpWindow) && helpWindow->HandlesHelp())
  3379.         {
  3380.             VPoint windowVPt(*((CPoint *)&globalMouse));
  3381.             helpWindow->SuperToLocal(windowVPt);
  3382.             helpWindow->HandleHelp(windowVPt, helpRegion);
  3383.  
  3384.             // Convert helpRegion region from window coords to global coords 
  3385.             helpWindow->LocalToSuperRegion(helpRegion);
  3386.         }
  3387.     }
  3388. } // TDispatcher::HandleHelp 
  3389.  
  3390. //----------------------------------------------------------------------------------------
  3391. // TDispatcher::TrackHelp: 
  3392. //----------------------------------------------------------------------------------------
  3393. #pragma segment MAApplicationRes
  3394.  
  3395. void TDispatcher::TrackHelp(CPoint globalMouse)
  3396. {
  3397.  
  3398. #if qDebugMsg
  3399.     if (PtInRgn(globalMouse, fHelpRegion))
  3400.     {
  3401.  
  3402.         if (gIntenseDebugging)
  3403.             fprintf(stderr, "cursor is in help region\n");
  3404.     }
  3405. #endif
  3406.  
  3407.     this->InvalidateHelpRgn();
  3408.  
  3409.     // Find out if the cursor is in a window which handles help, and if so, call
  3410.     // HandleHelp to allow some subview to show help, and compute a region
  3411.     this->HandleHelp(*((CPoint *)&globalMouse), fHelpRegion);
  3412.  
  3413.     if (EmptyRgn(fHelpRegion))
  3414.         this->DoShowHelp(globalMouse, fHelpRegion);
  3415.  
  3416.     // Make sure the cursorpoint is included 
  3417.     TView::PtAndRgn(globalMouse, fHelpRegion);
  3418.  
  3419. #if qDebugMsg
  3420.     if (gIntenseDebugging)
  3421.         if (fHelpRegion == NULL)
  3422.             fprintf(stderr, "fHelpRegion is NULL\n");
  3423. #endif
  3424.  
  3425. #if qDebug
  3426.     if (gIntenseDebugging && !PtInRgn(globalMouse, fHelpRegion))
  3427.     {
  3428.         CRect bBox = (*fHelpRegion)->rgnBBox;
  3429.         fprintf(stderr, "Whoops, help region was not correctly calculated.\n");
  3430.         fprintf(stderr, "global cursor = ", (const char*)globalMouse);
  3431.         fprintf(stderr, "  (*fHelpRegion)->rgnBBox = ", (const char*) bBox);
  3432.         fprintf(stderr, "\n");
  3433.         ProgramBreak("The cursor is not in the help region at end of TDispatcher.TrackHelp!");
  3434.     }
  3435. #endif
  3436.  
  3437. } // TDispatcher::TrackHelp 
  3438.  
  3439. //----------------------------------------------------------------------------------------
  3440. // TDispatcher::TrackMouse: 
  3441. //----------------------------------------------------------------------------------------
  3442. #pragma segment MADoCommand
  3443.  
  3444. TTracker* TDispatcher::TrackMouse(const VPoint& theMouse,
  3445.                                    CPoint hysteresis,
  3446.                                    TTracker* theCommand)
  3447. {
  3448.     MAVolatileInit(TTracker*, currentTracker, NULL);    // so failure handler works
  3449.     MAVolatileInit(TTracker*, volatileCommand, theCommand);    // so failure handler works
  3450.  
  3451.     FailInfo fi;
  3452.     Try(fi)
  3453.     {
  3454.         currentTracker = volatileCommand->HandleTrackBegin(theMouse, hysteresis);
  3455.         volatileCommand = NULL;                // so failure handler works
  3456.  
  3457.         while (currentTracker && !currentTracker->IsDoneTracking())
  3458.             if (this->IsFrontProcess())
  3459.                 currentTracker = currentTracker->HandleTrackContinue();
  3460.  
  3461.         if (currentTracker)
  3462.             currentTracker = currentTracker->HandleTrackEnd();
  3463.  
  3464.         fi.Success();
  3465.     }
  3466.     else // Recover
  3467.     {
  3468.         if (volatileCommand)
  3469.         {
  3470.             volatileCommand->Completed();
  3471.  
  3472.             if (volatileCommand->ShouldFreeOnCompletion())
  3473.                 volatileCommand = (TTracker*) FreeIfObject(volatileCommand);
  3474.         }
  3475.  
  3476.         if (currentTracker)
  3477.         {
  3478.             currentTracker->Completed();
  3479.  
  3480.             if (currentTracker->ShouldFreeOnCompletion())
  3481.                 currentTracker = (TTracker*) FreeIfObject(currentTracker);
  3482.         }
  3483.  
  3484.         fi.ReSignal();
  3485.     }
  3486.  
  3487.     return currentTracker;
  3488. } // TDispatcher::TrackMouse 
  3489.  
  3490. //----------------------------------------------------------------------------------------
  3491. // TDispatcher::UpdateAllWindows: 
  3492. //----------------------------------------------------------------------------------------
  3493. #pragma segment MAApplicationRes
  3494.  
  3495. void TDispatcher::UpdateAllWindows()
  3496. {
  3497.     TToolboxEvent * event;
  3498.  
  3499.     ++fEventLevel;
  3500.  
  3501.     // Something bad could happen here if for some reason the event queue was blocked (constipated?)
  3502.     // or something, causing us to loop forever. Let's put an unreasonable upper bound on the number
  3503.     // of events we'll handle in this loop.
  3504.  
  3505.     int maxEvents = 500;
  3506.     while ((event = this->GetEvent(updateMask | activMask, 0, NULL)) != NULL && maxEvents--)
  3507.         event->Process();
  3508.     --fEventLevel;
  3509. } // TDispatcher::UpdateAllWindows 
  3510.  
  3511. //----------------------------------------------------------------------------------------
  3512. // TDispatcher::DoMakeViewServer: 
  3513. //----------------------------------------------------------------------------------------
  3514. #pragma segment MAInit
  3515.  
  3516. void TDispatcher::DoMakeViewServer()
  3517. {
  3518.     TViewServer * aViewServer = new TViewServer;
  3519.     aViewServer->IViewServer();                    // assigns the global reference
  3520. } // TDispatcher::DoMakeViewServer 
  3521.  
  3522. //----------------------------------------------------------------------------------------
  3523. // TDispatcher::WMgrToWindow: 
  3524. //----------------------------------------------------------------------------------------
  3525. #pragma segment MAApplicationRes
  3526.  
  3527. TWindow* TDispatcher::WMgrToWindow(WindowRef aWindowPtr)
  3528. {
  3529.     // just uses the global routine in UWindow
  3530.     return TWindow::WMgrToWindow(aWindowPtr);
  3531. } // TDispatcher::WMgrToWindow 
  3532.  
  3533.  
  3534. //----------------------------------------------------------------------------------------
  3535. // TDispatcher::GetApplicationName: 
  3536. //----------------------------------------------------------------------------------------
  3537. #pragma segment MAWriteFile
  3538.  
  3539. void TDispatcher::GetApplicationName(CStr255& theName)
  3540. {
  3541.     FailInfo fi;
  3542.     Try(fi)
  3543.     {
  3544.         ProcessInfoRec info;
  3545.         info.processInfoLength = sizeof(ProcessInfoRec);
  3546.         info.processName = theName;
  3547.         info.processAppSpec = NULL;
  3548.         FailOSErr(GetProcessInformation(&fProcessNumber, &info));
  3549.         fi.Success();
  3550.     }
  3551.     else
  3552.     {
  3553. #if qDebug
  3554.         ProgramBreak("TDispatcher::GetApplicationName() failed!");
  3555. #endif
  3556.         // no need to fail completely, just return generic string
  3557.         theName = "<Application>";
  3558.         
  3559.         // Don't ReSignal
  3560.     }
  3561. } // TDispatcher::GetApplicationName 
  3562.  
  3563. //----------------------------------------------------------------------------------------
  3564. // TDispatcher::DoUndoRedo: 
  3565. //----------------------------------------------------------------------------------------
  3566. #pragma segment MAScriptingRes
  3567.  
  3568. Boolean TDispatcher::DoUndoRedo(TCommandHandler* theContext,
  3569.                                  CommandNumber aCommandNumber,
  3570.                                  MScriptableObject* theTarget)
  3571. // Handles the undo choice from the menu. If you want undo/redo to be recordable
  3572. // your DoMenuCommand method should call this on cUndo.
  3573. {
  3574.     TCommand * lastCommand = theContext->GetLastCommand();
  3575.     if (lastCommand && (lastCommand->fContext == theContext))
  3576.     {
  3577.         DescType theEventType;
  3578.         if (lastCommand->fCommandDone)
  3579.             theEventType = kAEUndo;
  3580.         else
  3581.             theEventType = kAERedo;
  3582.         TAppleEvent * theEvent = new TAppleEvent;
  3583.         theEvent->IAppleEvent(kAEMiscStandards, theEventType, gServerAddress, kAEWaitReply);
  3584.         CTempDesc targetDesc;
  3585.         theTarget->MakeObjectSpecifier(targetDesc, theTarget->GetSpecifierForm());
  3586.         theEvent->WriteParameter(keyDirectObject, targetDesc);
  3587.         TClientCommand * theCmd = new TClientCommand;
  3588.         theCmd->IClientCommand(aCommandNumber, theContext, FALSE, FALSE, theContext, theEvent);
  3589.         this->PostCommand(theCmd);
  3590.         return TRUE;
  3591.     }
  3592.     else
  3593.         return FALSE;
  3594. }
  3595.  
  3596. //----------------------------------------------------------------------------------------
  3597. // TDispatcher::UndoRedoInContext: 
  3598. //----------------------------------------------------------------------------------------
  3599. #pragma segment MAScriptingRes
  3600.  
  3601. Boolean TDispatcher::UndoRedoInContext(TCommandHandler* /*theContext*/,
  3602.                                         CommandNumber aCommandNumber)
  3603. // Handles the undo event. TDispatcher will handle this for itself, but if
  3604. // you handle undo/redo in another context you should call this from that object's
  3605. // DoScriptCommand method.
  3606. {
  3607.     Boolean        completed = FALSE;
  3608.     if (aCommandNumber == cAEUndo || aCommandNumber == cAERedo)
  3609.     {
  3610.         Boolean oldTempAlloc = TemporaryAllocation(TRUE);
  3611.         Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  3612.     
  3613.         // Generate the proper undo or redo command.
  3614.     
  3615.         if (aCommandNumber == cAEUndo)
  3616.         {
  3617.             TUndoCommand*        anUndoOrRedoCommand = NULL;
  3618.             anUndoOrRedoCommand = new TUndoCommand();
  3619.             anUndoOrRedoCommand->IUndoCommand(aCommandNumber);
  3620.             anUndoOrRedoCommand->Process();
  3621.         }
  3622.         else
  3623.         {
  3624.             TRedoCommand*        anUndoOrRedoCommand = NULL;
  3625.             anUndoOrRedoCommand = new TRedoCommand();
  3626.             anUndoOrRedoCommand->IRedoCommand(aCommandNumber);
  3627.             anUndoOrRedoCommand->Process();
  3628.         }
  3629.     
  3630.         TemporaryAllocation(oldTempAlloc);
  3631.         AllocateObjectsFromPerm(oldObjectPerm);
  3632.     
  3633.         completed = TRUE;
  3634.     }
  3635.     return completed;
  3636. }
  3637.  
  3638. //----------------------------------------------------------------------------------------
  3639. // TDispatcher::CountContainedObjects: 
  3640. //----------------------------------------------------------------------------------------
  3641. #pragma segment MAScriptingRes
  3642.  
  3643. long TDispatcher::CountContainedObjects(DescType desiredType)
  3644. {
  3645.     // Counts the number of windows or documents the application has open.
  3646.  
  3647.     long result = 0;
  3648.  
  3649.     switch (desiredType)
  3650.     {
  3651.         case cMenu:
  3652.             {
  3653.                 result = CountMenus(gMenuBarManager->fDisplayedMenus);
  3654.             }
  3655.             break;
  3656.  
  3657.         case cPalette:
  3658.         case cWindow:
  3659.             {
  3660.                 // Go through the window list and count the visible windows.
  3661.                 CWMgrIterator iter;
  3662.                 
  3663.                 for (WindowRef aWinPtr = iter.FirstWMgrWindow(); iter.More(); aWinPtr = iter.NextWMgrWindow())
  3664.                 {
  3665.                     TWindow * aWindow = this->WMgrToWindow(aWinPtr);
  3666.                     if ((aWindow) && aWindow->IsShown() && (aWindow->GetOMClass() == desiredType))
  3667.                         result++;
  3668.                 }
  3669.             }
  3670.             break;
  3671.  
  3672.         default:
  3673.             {
  3674.                 // Go through the document list and count the documents of this type.
  3675.                 CNoGhostDocsIterator iter(this);
  3676.                 for (TDocument * aDocument = iter.FirstDocument(); iter.More(); aDocument = iter.NextDocument())
  3677.                     if ((aDocument->GetOMClass() == desiredType) || (desiredType == cDocument))
  3678.                         result++;
  3679.             }
  3680.             break;
  3681.     }
  3682.  
  3683.     return result;
  3684. }
  3685.  
  3686. #if qAttachable
  3687.  
  3688. //----------------------------------------------------------------------------------------
  3689. // TDispatcher::HandleOSAEvent:
  3690. //----------------------------------------------------------------------------------------
  3691. #pragma segment MAScriptingRes
  3692.  
  3693. Boolean TDispatcher::HandleOSAEvent(CommandNumber    aCommandNumber,
  3694.                                     TAppleEvent* message,
  3695.                                     TAppleEvent* reply)
  3696. {
  3697.     // Don't give OSA the run event so that scripts won't have to continue it.
  3698.     return (aCommandNumber != cFinderNew) && MScriptableObject::HandleOSAEvent(aCommandNumber, message, reply);
  3699. }
  3700.  
  3701. #endif // qAttachable
  3702.  
  3703. //----------------------------------------------------------------------------------------
  3704. // TDispatcher::DoScriptCommand: 
  3705. //----------------------------------------------------------------------------------------
  3706. #pragma segment MAScriptingRes
  3707.  
  3708. void TDispatcher::DoScriptCommand(CommandNumber    aCommandNumber,
  3709.                                     TAppleEvent*     message,
  3710.                                        TAppleEvent*     reply)
  3711. {
  3712.     TEventHandler * theTarget = this->GetTarget();
  3713.  
  3714.     switch (aCommandNumber)
  3715.     {
  3716.         case cAEUndo:
  3717.         case cAERedo:
  3718.             if (CommandEnabled(cUndo))
  3719.                 this->UndoRedoInContext(this, aCommandNumber);
  3720.             break;
  3721.  
  3722.         case cAEPaste:
  3723.             if (CommandEnabled(cPaste))
  3724.                 theTarget->HandleMenuCommand(cPaste);
  3725.             break;
  3726.  
  3727.         case cAECut:
  3728.             if (CommandEnabled(cCut))
  3729.                 theTarget->HandleMenuCommand(cCut);
  3730.             break;
  3731.  
  3732.         case cAECopy:
  3733.             if (CommandEnabled(cCopy))
  3734.                 theTarget->HandleMenuCommand(cCopy);
  3735.             break;
  3736.  
  3737.         default:
  3738.             MDefaultScriptableObject::DoScriptCommand(aCommandNumber, message, reply);
  3739.             break;
  3740.     }
  3741. }
  3742.  
  3743. //----------------------------------------------------------------------------------------
  3744. // TDispatcher::SetObjectProperty: 
  3745. //----------------------------------------------------------------------------------------
  3746. #pragma segment MAScriptingRes
  3747.  
  3748. void TDispatcher::SetObjectProperty(const CAEDesc& thePropertyValue,
  3749.                                      DescType whichProperty)
  3750. {
  3751.     CAEDesc localPropValue = thePropertyValue;
  3752.     switch (whichProperty)
  3753.     {
  3754.         case pClipboard:
  3755.             {
  3756.                 gClipboardMgr->AboutToLoseControl(TRUE);// so scrap gets converted
  3757.                 FailOSErr((short)ZeroScrap());
  3758.                 if (localPropValue.GetDescriptorType() == typeAEList)
  3759.                 {
  3760.                     // Put all the elements of the list on the scrap
  3761.                     long count = 0;
  3762.                     FailOSErr(AECountItems(localPropValue, &count));
  3763.                     while (count)
  3764.                     {
  3765.                         CTempDesc theScrapData;
  3766.                         DescType theAEKeyword;
  3767.                         FailOSErr(AEGetNthDesc(localPropValue, count--, typeWildCard, &theAEKeyword, theScrapData));
  3768.                         gClipboardMgr->PutDeskScrapData(theScrapData.GetDescriptorType(), theScrapData.GetDataHandle());
  3769.                     }
  3770.                 }
  3771.                 else
  3772.                 {
  3773.                     gClipboardMgr->PutDeskScrapData(localPropValue.GetDescriptorType(), localPropValue.GetDataHandle());
  3774.                 }
  3775.                 gClipboardMgr->RegainControl(TRUE);// so scrap gets converted
  3776.             }
  3777.             break;
  3778.  
  3779.         case pName:
  3780.         case pIsFrontProcess:
  3781.         case pVersion:
  3782.         case pUserSelection:
  3783.             FailOSErr(errAECantSetReadOnly);
  3784.             break;
  3785.  
  3786.         default:
  3787.             MScriptableObject::SetObjectProperty(thePropertyValue, whichProperty);
  3788.             break;
  3789.     }
  3790. }
  3791.  
  3792. //----------------------------------------------------------------------------------------
  3793. // TDispatcher::GetObjectProperty: 
  3794. //----------------------------------------------------------------------------------------
  3795. #pragma segment MAScriptingRes
  3796.  
  3797. Boolean TDispatcher::GetObjectProperty(CAEDesc& thePropertyValue,
  3798.                                         DescType whichProperty,
  3799.                                         const CAEDesc& desiredType)
  3800. {
  3801.     // Return properties for the application.
  3802.     Boolean hasProperty = TRUE;
  3803.     
  3804.     FailInfo fi;
  3805.     Try(fi)
  3806.     {
  3807.         switch (whichProperty)
  3808.         {
  3809.             case pClipboard:
  3810.                 {
  3811.                     // Since we don't know what's on the scrap and we're trying to return
  3812.                     // its contents in a generic way, we'll get the desk scrap handle
  3813.                     // and walk down it grabbing each scrap type we come upon.
  3814.                     Boolean inFront = this->IsFrontProcess();
  3815.                     if (inFront)
  3816.                     {
  3817.                         gClipboardMgr->AboutToLoseControl(TRUE);// so scrap gets converted
  3818.                         gClipboardMgr->RegainControl(TRUE);// so scrap gets converted
  3819.                     }
  3820.                     FailOSErr((short)LoadScrap());
  3821.                     PScrapStuff pScrpInf = InfoScrap();
  3822.                     Handle theScrap = pScrpInf->scrapHandle;
  3823.                     MAVolatileInit(THandleStream*, theScrapStream, NULL);
  3824.                     MAVolatileInit(Handle, theScrapData, NULL);
  3825.  
  3826.                     FailInfo scrapFail;
  3827.                     Try(scrapFail)
  3828.                     {
  3829.                         theScrapStream = new THandleStream;
  3830.                         theScrapData = NewPermHandle(0);
  3831.                         theScrapStream->IHandleStream(theScrap, 0);
  3832.     
  3833.                         thePropertyValue.CreateList();
  3834.     
  3835.                         while ((theScrapStream->GetPosition() + 8) < pScrpInf->scrapSize)
  3836.                         {
  3837.                             DescType theScrapType = (DescType)theScrapStream->ReadLong();
  3838.                             long theLength = theScrapStream->ReadLong();
  3839.                             SetPermHandleSize(theScrapData, theLength);
  3840.                             FailMemError();
  3841.                             SignedByte wasState = LockHandle(theScrapData);
  3842.                             theScrapStream->ReadBytes(*theScrapData, theLength);
  3843.                             HSetState(theScrapData, wasState);
  3844.                             CAEDesc theScrapDesc(theScrapType, theScrapData);
  3845.                             FailOSErr(AEPutDesc(thePropertyValue, 0, theScrapDesc));
  3846.                         }
  3847.                         theScrapData = DisposeIfHandle(theScrapData);
  3848.                         theScrapStream = (THandleStream *)FreeIfObject(theScrapStream);
  3849.                         scrapFail.Success();
  3850.                     }
  3851.                     else
  3852.                     {
  3853.                         theScrapData = DisposeIfHandle(theScrapData);
  3854.                         theScrapStream = (THandleStream *)FreeIfObject(theScrapStream);
  3855.                         scrapFail.ReSignal();
  3856.                     }
  3857.                 }
  3858.                 break;
  3859.     
  3860.             case pName:
  3861.                 {
  3862.                     CStr255 theAppName;
  3863.                     GetApplicationName(theAppName);
  3864.                     thePropertyValue.PutString(theAppName);
  3865.                 }
  3866.                 break;
  3867.     
  3868.             case pIsFrontProcess:
  3869.                 thePropertyValue.PutBoolean(this->IsFrontProcess());
  3870.                 break;
  3871.     
  3872.             case pVersion:
  3873.                 {
  3874.                     short refNum = MACurResFile();    // save current resource
  3875.                     Handle theVersResource = NULL;
  3876.                     FailResError();
  3877.                     FailInfo versionFail;
  3878.                     Try(versionFail)
  3879.                     {
  3880.                         CAEDesc propData;
  3881.                         MAUseResFile(gApplicationRefNum);// set this resource to be current
  3882.                         theVersResource = (Handle)Get1Resource((ResType)'vers', 1);
  3883.                         SignedByte wasState = LockHandle(theVersResource);
  3884.                         FailOSErr(AECreateDesc(typeVersion, *theVersResource, GetHandleSize(theVersResource), propData));
  3885.                         thePropertyValue = propData;
  3886.                         HSetState(theVersResource, wasState);
  3887.                         ReleaseResource(theVersResource);
  3888.                         MAUseResFile(refNum);            // reset back to resource previously set
  3889.                         versionFail.Success();
  3890.                     }
  3891.                     else
  3892.                     {
  3893.                         HUnlock(theVersResource);
  3894.                         ReleaseResource(theVersResource);
  3895.                         MAUseResFile(refNum);            // reset back to resource previously set
  3896.                         versionFail.ReSignal();
  3897.                     }
  3898.                 }
  3899.                 break;
  3900.     
  3901.             case pUserSelection:
  3902.                 {
  3903.                     TWindow * theFrontWindow = this->GetFrontWindow();
  3904.                     if (theFrontWindow)
  3905.                     {
  3906.                         TDocument * theDoc = theFrontWindow->fDocument;
  3907.                         if (theDoc)
  3908.                         {
  3909.                             TDesignator *theUserSelection = theDoc->GetUserSelection();
  3910.                             FailNonObject(theUserSelection);
  3911.                                 
  3912.                             CAEDesc propData;
  3913.                             theUserSelection->MakeObjectSpecifier(propData, formPropertyID);
  3914.                             thePropertyValue = propData;
  3915.                         }
  3916.                     }
  3917.                 }
  3918.                 break;
  3919.     
  3920.             default:
  3921.                 hasProperty = MScriptableObject::GetObjectProperty(thePropertyValue, whichProperty, desiredType);
  3922.                 break;
  3923.         }
  3924.         fi.Success();
  3925.     }
  3926.     else
  3927.     {
  3928.         // we failed while trying to get the property
  3929.         hasProperty = FALSE;
  3930.         
  3931.         // Don't ReSignal
  3932.     }
  3933.     return hasProperty;
  3934. }
  3935.  
  3936. //----------------------------------------------------------------------------------------
  3937. // TDispatcher::MakeObjectSpecifier: 
  3938. //----------------------------------------------------------------------------------------
  3939. #pragma segment MAScriptingRes
  3940.  
  3941. Boolean TDispatcher::MakeObjectSpecifier(CAEDesc& theObjectSpecifier,
  3942.                                              DescType /*preferredForm*/)
  3943. {
  3944.     //return (AECreateDesc(typeNull, NULL, 0, theObjectSpecifier) == noErr);
  3945.     FailOSErr(AECreateDesc(typeNull, NULL, 0, theObjectSpecifier));
  3946.     return TRUE;
  3947. }
  3948.  
  3949. //----------------------------------------------------------------------------------------
  3950. // TDispatcher::GetContainedObject: 
  3951. //----------------------------------------------------------------------------------------
  3952. #pragma segment OSLDispatchRes
  3953.  
  3954. MScriptableObject* TDispatcher::GetContainedObject(DescType desiredType,
  3955.                                                     DescType selectionForm,
  3956.                                                     const CAEDesc& selectionData)
  3957. {
  3958.     MScriptableObject * result = NULL;
  3959.     
  3960.     if (desiredType == cFile)
  3961.     {
  3962.         // When you script 'file "Macintosh HD:My File"' AppleScript will
  3963.         // give the app a pathname and expect a file object in return.
  3964.         TFile * resultFile = this->DoMakeFile(cOpen);
  3965.         CStr255 thePathName;
  3966.         selectionData.GetString(thePathName);
  3967.         resultFile->SpecifyWithTrio(0, 0, (CStr63 &)thePathName);
  3968.         TOSADispatcher::fgDispatcher->AddTemporaryToken(resultFile);
  3969.         result = resultFile;
  3970.     }
  3971.     else if (desiredType == cDocument && selectionForm == formName)
  3972.     {
  3973.         // We know we're going after a document with a 
  3974.         // specific name so just scan the document list.
  3975.         CStr255                    theDocName;
  3976.         CNoGhostDocsIterator    iter(this);
  3977.         TDocument*                aDocument = iter.FirstDocument();
  3978.         
  3979.         selectionData.GetString(theDocName);
  3980.         do
  3981.         {
  3982.             if ((aDocument->GetOMClass() == desiredType)
  3983.                 && (aDocument->fTitle == theDocName))    // Should this be IUEqualString?
  3984.                 result = aDocument;
  3985.             aDocument = iter.NextDocument();
  3986.         } while (result == NULL && iter.More());
  3987.     }
  3988.     else
  3989.         result = MScriptableObject::GetContainedObject(desiredType, selectionForm, selectionData);
  3990.     
  3991.     return result;
  3992. }
  3993.  
  3994. //----------------------------------------------------------------------------------------
  3995. // TDispatcher::GetIndContainedObject: 
  3996. //----------------------------------------------------------------------------------------
  3997. #pragma segment OSLDispatchRes
  3998.  
  3999. MScriptableObject* TDispatcher::GetIndContainedObject(DescType desiredType,
  4000.                                                        long     index)
  4001. {
  4002.     MScriptableObject *indexedObject;
  4003.     
  4004.     switch(desiredType)
  4005.     {
  4006.         case cWindow:
  4007.             indexedObject = GetWindowByIndex((short)index);
  4008.             break;
  4009.         
  4010.         case cPalette:
  4011.             indexedObject = GetPaletteByIndex((short)index);
  4012.             break;
  4013.             
  4014.         case cMenu:
  4015.             {
  4016.                 // Create a menu accessor to handle events for this menu
  4017.                 MenuRef theMenuRef = GetIndMenu(gMenuBarManager->fDisplayedMenus, (short)index);
  4018.                 if (theMenuRef == NULL)
  4019.                     return NULL; // no such menu
  4020.                 TMenuAccessor* theAccessor = new TMenuAccessor;
  4021.                 theAccessor->IMenuAccessor(theMenuRef, (short)index);
  4022.                 TOSADispatcher::fgDispatcher->AddTemporaryToken(theAccessor);
  4023.                 indexedObject = theAccessor;
  4024.             }
  4025.             break;
  4026.         
  4027.         default:
  4028.             if (IsDocumentClass(desiredType))
  4029.                 indexedObject = GetDocumentByIndex(desiredType, (short)index);
  4030.             else
  4031.                 indexedObject = MScriptableObject::GetIndContainedObject(desiredType, index);
  4032.             break;
  4033.     }
  4034.     return indexedObject;
  4035. }
  4036.  
  4037. //----------------------------------------------------------------------------------------
  4038. // TDispatcher::GetWindowByIndex: 
  4039. //----------------------------------------------------------------------------------------
  4040. #pragma segment OSLDispatchRes
  4041.  
  4042. TWindow* TDispatcher::GetWindowByIndex(short wIndex)
  4043. {
  4044.     CWMgrIterator     iter;
  4045.     short            windowCount = 0;
  4046.     TWindow            *indexedWindow = NULL;
  4047.     TWindow            *tempWindow;
  4048.     
  4049.     for (WindowRef aWinPtr = iter.FirstWMgrWindow(); (windowCount < wIndex) && iter.More();
  4050.         aWinPtr = iter.NextWMgrWindow())
  4051.     {
  4052.         if (!TWindow::IsFloatWindow(aWinPtr))
  4053.         {
  4054.             tempWindow = this->WMgrToWindow(aWinPtr);
  4055.             if (tempWindow && tempWindow->IsShown())
  4056.             {
  4057.                 windowCount++;
  4058.                 if (windowCount == wIndex)
  4059.                     indexedWindow = tempWindow;
  4060.             }
  4061.         }
  4062.     }
  4063.     return indexedWindow;
  4064. }
  4065.  
  4066. //----------------------------------------------------------------------------------------
  4067. // TDispatcher::GetPaletteByIndex: 
  4068. //----------------------------------------------------------------------------------------
  4069. #pragma segment OSLDispatchRes
  4070.  
  4071. TWindow* TDispatcher::GetPaletteByIndex(short index)
  4072. {
  4073.     CWMgrIterator     iter;
  4074.     short            paletteCount = 0;
  4075.     TWindow            *indexedPalette = NULL;
  4076.     TWindow            *tempWindow;
  4077.     
  4078.     for (WindowRef aWinPtr = iter.FirstWMgrWindow(); (paletteCount < index) && iter.More(); 
  4079.             aWinPtr = iter.NextWMgrWindow())
  4080.     {
  4081.         if (TWindow::IsFloatWindow(aWinPtr))
  4082.         {
  4083.             tempWindow = this->WMgrToWindow(aWinPtr);
  4084.             if (tempWindow && tempWindow->IsShown())
  4085.             {
  4086.                 paletteCount++;
  4087.                 if (paletteCount == index)
  4088.                     indexedPalette = tempWindow;
  4089.             }
  4090.         }
  4091.     }
  4092.     return indexedPalette;
  4093. }
  4094.  
  4095. //----------------------------------------------------------------------------------------
  4096. // TDispatcher::GetDocumentByIndex: 
  4097. //----------------------------------------------------------------------------------------
  4098. #pragma segment MAScriptingRes
  4099.  
  4100. TDocument* TDispatcher::GetDocumentByIndex(DescType desiredType,
  4101.                                             short wIndex)
  4102. {
  4103.     // Go through the window list and count to the Nth window associated with a document
  4104.     // of the desired type.  Only count the first window for each document just
  4105.     // in case a document has more than one window.
  4106.     TWindow*        aWindow = NULL;
  4107.     TWindow*        theFrontWindow = GetFrontWindow();
  4108.     TDocument*        aDocument = NULL;
  4109.     
  4110.     if (theFrontWindow)
  4111.     {
  4112.         // Make a list for all of the documents we find until we find the one we want.
  4113.         TDynamicArray*        aDocList = new TDynamicArray;
  4114.         aDocList->IDynamicArray(20, sizeof(TDocument*));
  4115.  
  4116.         WindowRef theWindowPtr = theFrontWindow->fWMgrWindow;
  4117.         short index = 0;
  4118.         while ((theWindowPtr != NULL) && (index < wIndex))
  4119.         {
  4120.             aWindow = this->WMgrToWindow(theWindowPtr);
  4121.             if (aWindow)
  4122.             {
  4123.                 aDocument = aWindow->fDocument;
  4124.                  if (aDocument && (aDocument->GetOMClass() == desiredType))
  4125.                 {
  4126.                     // See if this document is already in the list.
  4127.                     CArrayIterator    iter(aDocList);
  4128.                     Boolean            found = FALSE;
  4129.                     
  4130.                     for (ArrayIndex i = iter.FirstIndex(); iter.More() && !found; i = iter.NextIndex())
  4131.                       found = (aDocument == (TDocument*)((*aDocList)[i]));
  4132.  
  4133.                     if (!found)
  4134.                     {
  4135.                         index++;
  4136.                         aDocList->InsertElementsBefore(aDocList->GetSize() + 1, &aDocument, 1);
  4137.                     }
  4138.                 }
  4139.             }
  4140.             theWindowPtr = GetNextWindow(theWindowPtr);
  4141.         }
  4142.         aDocList->Free();
  4143.     }
  4144.     return aDocument;
  4145. }
  4146.  
  4147. //----------------------------------------------------------------------------------------
  4148. // TDispatcher::IsDocumentClass: 
  4149. //----------------------------------------------------------------------------------------
  4150. #pragma segment OSLDispatchRes
  4151.  
  4152. Boolean TDispatcher::IsDocumentClass(DescType desiredType)
  4153. {
  4154.     return desiredType == cDocument;
  4155. }
  4156.  
  4157. //----------------------------------------------------------------------------------------
  4158. // TDispatcher::ReportReplyError: 
  4159. //----------------------------------------------------------------------------------------
  4160. #pragma segment MAScriptingRes
  4161.  
  4162. void TDispatcher::ReportReplyError(CommandNumber/*fromCmdNum*/ ,
  4163.                                     OSErr theError,
  4164.                                     const CStr255& theErrStr)
  4165. {
  4166.     // When a TClientCommand gets an error back from an AppleEvent it calls this
  4167.     // method so the application can report the error on the client side.
  4168.     if (theErrStr.Length())
  4169.     {
  4170.         ParamText(theErrStr, gEmptyString, gEmptyString, gEmptyString);
  4171.         StdAlert(phUnknownErr);
  4172.         ResetAlertStage();
  4173.     }
  4174.     else if (theError != noErr)
  4175.         ErrorAlert(theError, 0);
  4176. }
  4177.  
  4178. #if qContainer
  4179. //------------------------------------------------------------------------------------
  4180. // Container Application Support
  4181. //------------------------------------------------------------------------------------
  4182.  
  4183. // The following five functions are static.  The must be resident!
  4184.  
  4185. // Huh? They just need to be in the jump table. 
  4186.  
  4187. //----------------------------------------------------------------------------------------
  4188. // TDispatcher::FocusAcquiredProc: 
  4189. //----------------------------------------------------------------------------------------
  4190. #pragma segment MAApplicationRes
  4191.  
  4192. void TDispatcher::FocusAcquiredProc(CADocumentRef aCADocRef, CAFocusType focusType)
  4193. {
  4194.     // Save current port.  i.e. GetPort (&savePort);
  4195.     
  4196.     // Focus on the documents window.
  4197.     
  4198.     switch (focusType)
  4199.     {
  4200.     
  4201.         case kCAPrimaryFocus:
  4202.         
  4203.             gHasODFocus = TRUE;
  4204.             
  4205.             // Save the focus document
  4206.             gDispatcher->fCurrentDocument = aCADocRef;
  4207.  
  4208.             // Set and draw the app menu bar
  4209.             if (gMenuBarManager->fAppMenuBar)
  4210.             {
  4211.                 ::SetMenuBar(gMenuBarManager->fAppMenuBar);
  4212.                 ::DrawMenuBar(); //MacApp thinks the menus have not changed
  4213.             }
  4214.             
  4215.             // Invalidate selection regions
  4216.             break;
  4217.             
  4218.         case kCAModalFocus:
  4219.             gHasODModalFocus = TRUE;
  4220.             break;    
  4221.                 
  4222.         default:
  4223.             break;
  4224.             
  4225.     }
  4226.     // Refocus on the original port.  i.e. SetPort (savePort);
  4227.     
  4228. }
  4229.  
  4230. //----------------------------------------------------------------------------------------
  4231. // TDispatcher::FocusLostProc: 
  4232. //----------------------------------------------------------------------------------------
  4233. #pragma segment MAApplicationRes
  4234.  
  4235. void TDispatcher::FocusLostProc(CADocumentRef aCADocRef, CAFocusType focusType)
  4236. {
  4237.     // Save current port.  i.e. GetPort (&savePort);
  4238.     
  4239.     // Focus on the documents window.
  4240.     
  4241.     switch (focusType)
  4242.     {            
  4243.     
  4244.         case kCAPrimaryFocus:
  4245.             
  4246.             gHasODFocus = FALSE;
  4247.  
  4248.             // We no longer have the currently focused document.
  4249.             gDispatcher->fCurrentDocument = NULL;
  4250.             
  4251.             // Invalidate the selection indicators.
  4252.  
  4253.             break;
  4254.             
  4255.         case kCAModalFocus:
  4256.             gHasODModalFocus = FALSE;
  4257.             break;
  4258.                 
  4259.                 
  4260.         default:
  4261.             break;
  4262.     }
  4263.     
  4264.     // Refocus on the original port.  i.e. SetPort (savePort);
  4265.  
  4266. }
  4267.  
  4268. //----------------------------------------------------------------------------------------
  4269. // TDispatcher::WindowActivateHandler: 
  4270. //----------------------------------------------------------------------------------------
  4271. #pragma segment MAApplicationRes
  4272.  
  4273. void TDispatcher::WindowActivateHandler(WindowPtr theWindow, Boolean activating)
  4274. {
  4275.     //TWindow * aWindow = gDispatcher->WMgrToWindow((WindowRef)(event->fEventRecord.message));
  4276.     TWindow * aWindow = gDispatcher->WMgrToWindow((WindowRef)FrontWindow());
  4277.  
  4278.     if (aWindow)
  4279.     {
  4280.         if (aWindow->fFloats)                                // ignore floaters
  4281.         {
  4282.             TWindow* frontWindow = gDispatcher->GetFrontWindow();    // find frontmost non-floating window
  4283.             if (frontWindow)
  4284.             {
  4285.                 aWindow = frontWindow;                        // (de)activate it instead of the floater
  4286.                 HiliteWindow(aWindow->fWMgrWindow, activating);
  4287.             }
  4288.         }
  4289.         aWindow->Activate(activating);
  4290.     }
  4291. }
  4292.  
  4293. //----------------------------------------------------------------------------------------
  4294. // TDispatcher::FrameShapeRequestHandler: 
  4295. //----------------------------------------------------------------------------------------
  4296. #pragma segment MAApplicationRes
  4297.  
  4298. pascal Boolean TDispatcher::FrameShapeRequestHandler(CADocumentRef aCADocRef,
  4299.                                                      CAFrameRef frameRef,
  4300.                                                      RgnHandle aRgn)
  4301. {
  4302.     // Iterate over the embedded frames of a document (Document has list?)
  4303.     // Find frame that it wants via frameRef
  4304.     // Ask the corresponding view if it will change.
  4305.     
  4306.     Boolean grantedRequest = FALSE;
  4307.     
  4308.     CCADocumentIterator iter(gDispatcher);
  4309.  
  4310.     for (TFileBasedDocument * aCADocument = iter.FirstDocument(); iter.More(); aCADocument = iter.NextDocument())
  4311.     {
  4312.         if(aCADocument->GetContainer() == aCADocRef)
  4313.         {    
  4314.             CODPartViewIterator viewIter(aCADocument);
  4315.  
  4316.             for (TODPartView * anODView = viewIter.FirstODPartView(); viewIter.More(); anODView = viewIter.NextODPartView())
  4317.                 if (anODView->GetFrameRef() == frameRef)
  4318.                     grantedRequest = anODView->NegotiateFrameChange(aRgn);
  4319.         }
  4320.     }    
  4321.     
  4322.     return grantedRequest;
  4323. }
  4324.  
  4325. //----------------------------------------------------------------------------------------
  4326. // TDispatcher::AdjustBorderHandler: 
  4327. //----------------------------------------------------------------------------------------
  4328. #pragma segment MAApplicationRes
  4329.  
  4330. Boolean    TDispatcher::AdjustBorderHandler(CADocumentRef aCADocRef,
  4331.                                          CAFrameRef frameRef,
  4332.                                          RgnHandle aRgn)
  4333. {
  4334.     return FALSE;
  4335. }
  4336.  
  4337. #endif // qContainer
  4338.  
  4339. //----------------------------------------------------------------------------------------
  4340. // End of UDispatcher.cp 
  4341.  
  4342. #pragma segment Inline
  4343.